📄 storage.c
字号:
*/
ULONG WINAPI IStream_fnRelease(IStream* iface) {
IStream32Impl *This = (IStream32Impl *)iface;
ULONG ref;
FlushFileBuffers(This->hf);
ref = InterlockedDecrement(&This->ref);
if (!ref) {
CloseHandle(This->hf);
HeapFree( GetProcessHeap(), 0, This );
}
return ref;
}
/******************************************************************************
* IStorage16_QueryInterface [STORAGE.500]
*/
HRESULT CDECL IStorage16_fnQueryInterface(
IStorage16* iface,REFIID refiid,LPVOID *obj
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
TRACE_(relay)("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
*obj = This;
return 0;
}
return OLE_E_ENUM_NOMORE;
}
/******************************************************************************
* IStorage16_AddRef [STORAGE.501]
*/
ULONG CDECL IStorage16_fnAddRef(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
* IStorage16_Release [STORAGE.502]
*/
ULONG CDECL IStorage16_fnRelease(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
ULONG ref;
ref = InterlockedDecrement(&This->ref);
if (!ref)
{
UnMapLS( This->thisptr );
HeapFree( GetProcessHeap(), 0, This );
}
return ref;
}
/******************************************************************************
* IStorage16_Stat [STORAGE.517]
*/
HRESULT CDECL IStorage16_fnStat(
LPSTORAGE16 iface,STATSTG16 *pstatstg, DWORD grfStatFlag
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
DWORD len = WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, NULL, 0, NULL, NULL );
LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, len );
TRACE("(%p)->(%p,0x%08x)\n",
This,pstatstg,grfStatFlag
);
WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, nameA, len, NULL, NULL );
pstatstg->pwcsName=(LPOLESTR16)MapLS( nameA );
pstatstg->type = This->stde.pps_type;
pstatstg->cbSize.u.LowPart = This->stde.pps_size;
pstatstg->mtime = This->stde.pps_ft1; /* FIXME */ /* why? */
pstatstg->atime = This->stde.pps_ft2; /* FIXME */
pstatstg->ctime = This->stde.pps_ft2; /* FIXME */
pstatstg->grfMode = 0; /* FIXME */
pstatstg->grfLocksSupported = 0; /* FIXME */
pstatstg->clsid = This->stde.pps_guid;
pstatstg->grfStateBits = 0; /* FIXME */
pstatstg->reserved = 0;
return S_OK;
}
/******************************************************************************
* IStorage16_Commit [STORAGE.509]
*/
HRESULT CDECL IStorage16_fnCommit(
LPSTORAGE16 iface,DWORD commitflags
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("(%p)->(0x%08x),STUB!\n",
This,commitflags
);
return S_OK;
}
/******************************************************************************
* IStorage16_CopyTo [STORAGE.507]
*/
HRESULT CDECL IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiidExclude,SNB16 SNB16Exclude,IStorage16 *pstgDest) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("IStorage16(%p)->(0x%08x,%s,%p,%p),stub!\n",
This,ciidExclude,debugstr_guid(rgiidExclude),SNB16Exclude,pstgDest
);
return S_OK;
}
/******************************************************************************
* IStorage16_CreateStorage [STORAGE.505]
*/
HRESULT CDECL IStorage16_fnCreateStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD dwStgFormat,DWORD reserved2, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
IStorage16Impl* lpstg;
int ppsent,x;
struct storage_pps_entry stde;
struct storage_header sth;
BOOL ret;
int nPPSEntries;
READ_HEADER(&This->str);
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,dwStgFormat,reserved2,ppstg
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istorage16(ppstg);
lpstg = MapSL((SEGPTR)*ppstg);
if (This->str.hf) {
DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
&lpstg->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
} else {
lpstg->str.lockbytes = This->str.lockbytes;
_ilockbytes16_addref(This->str.lockbytes);
}
ppsent=STORAGE_get_free_pps_entry(&lpstg->str);
if (ppsent<0)
return E_FAIL;
stde=This->stde;
if (stde.pps_dir==-1) {
stde.pps_dir = ppsent;
x = This->ppsent;
} else {
FIXME(" use prev chain too ?\n");
x=stde.pps_dir;
if (1!=STORAGE_get_pps_entry(&lpstg->str,x,&stde))
return E_FAIL;
while (stde.pps_next!=-1) {
x=stde.pps_next;
if (1!=STORAGE_get_pps_entry(&lpstg->str,x,&stde))
return E_FAIL;
}
stde.pps_next = ppsent;
}
ret = STORAGE_put_pps_entry(&lpstg->str,x,&stde);
assert(ret);
nPPSEntries = STORAGE_get_pps_entry(&lpstg->str,ppsent,&(lpstg->stde));
assert(nPPSEntries == 1);
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, lpstg->stde.pps_rawname,
sizeof(lpstg->stde.pps_rawname)/sizeof(WCHAR));
lpstg->stde.pps_sizeofname = (strlenW(lpstg->stde.pps_rawname)+1)*sizeof(WCHAR);
lpstg->stde.pps_next = -1;
lpstg->stde.pps_prev = -1;
lpstg->stde.pps_dir = -1;
lpstg->stde.pps_sb = -1;
lpstg->stde.pps_size = 0;
lpstg->stde.pps_type = 1;
lpstg->ppsent = ppsent;
/* FIXME: timestamps? */
if (!STORAGE_put_pps_entry(&lpstg->str,ppsent,&(lpstg->stde)))
return E_FAIL;
return S_OK;
}
/******************************************************************************
* IStorage16_CreateStream [STORAGE.503]
*/
HRESULT CDECL IStorage16_fnCreateStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
IStream16Impl* lpstr;
int ppsent,x;
struct storage_pps_entry stde;
BOOL ret;
int nPPSEntries;
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,reserved1,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm);
lpstr = MapSL((SEGPTR)*ppstm);
if (This->str.hf) {
DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
&lpstr->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
} else {
lpstr->str.lockbytes = This->str.lockbytes;
_ilockbytes16_addref(This->str.lockbytes);
}
lpstr->offset.u.LowPart = 0;
lpstr->offset.u.HighPart= 0;
ppsent=STORAGE_get_free_pps_entry(&lpstr->str);
if (ppsent<0)
return E_FAIL;
stde=This->stde;
if (stde.pps_next==-1)
x=This->ppsent;
else
while (stde.pps_next!=-1) {
x=stde.pps_next;
if (1!=STORAGE_get_pps_entry(&lpstr->str,x,&stde))
return E_FAIL;
}
stde.pps_next = ppsent;
ret = STORAGE_put_pps_entry(&lpstr->str,x,&stde);
assert(ret);
nPPSEntries = STORAGE_get_pps_entry(&lpstr->str,ppsent,&(lpstr->stde));
assert(nPPSEntries == 1);
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, lpstr->stde.pps_rawname,
sizeof(lpstr->stde.pps_rawname)/sizeof(WCHAR));
lpstr->stde.pps_sizeofname = (strlenW(lpstr->stde.pps_rawname)+1) * sizeof(WCHAR);
lpstr->stde.pps_next = -1;
lpstr->stde.pps_prev = -1;
lpstr->stde.pps_dir = -1;
lpstr->stde.pps_sb = -1;
lpstr->stde.pps_size = 0;
lpstr->stde.pps_type = 2;
lpstr->ppsent = ppsent;
/* FIXME: timestamps? */
if (!STORAGE_put_pps_entry(&lpstr->str,ppsent,&(lpstr->stde)))
return E_FAIL;
return S_OK;
}
/******************************************************************************
* IStorage16_OpenStorage [STORAGE.506]
*/
HRESULT CDECL IStorage16_fnOpenStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, IStorage16 *pstgPrio, DWORD grfMode, SNB16 snbExclude, DWORD reserved, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
IStream16Impl* lpstg;
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08x,%p,0x%08x,%p)\n",
This,pwcsName,pstgPrio,grfMode,snbExclude,reserved,ppstg
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istorage16(ppstg);
lpstg = MapSL((SEGPTR)*ppstg);
if (This->str.hf) {
DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
&lpstg->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
} else {
lpstg->str.lockbytes = This->str.lockbytes;
_ilockbytes16_addref(This->str.lockbytes);
}
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, name, sizeof(name)/sizeof(WCHAR));
newpps = STORAGE_look_for_named_pps(&lpstg->str,This->stde.pps_dir,name);
if (newpps==-1) {
IStream16_fnRelease((IStream16*)lpstg);
return E_FAIL;
}
if (1!=STORAGE_get_pps_entry(&lpstg->str,newpps,&(lpstg->stde))) {
IStream16_fnRelease((IStream16*)lpstg);
return E_FAIL;
}
lpstg->ppsent = newpps;
return S_OK;
}
/******************************************************************************
* IStorage16_OpenStream [STORAGE.504]
*/
HRESULT CDECL IStorage16_fnOpenStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
IStream16Impl* lpstr;
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p)\n",
This,pwcsName,reserved1,grfMode,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
FIXME("We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm);
lpstr = MapSL((SEGPTR)*ppstm);
if (This->str.hf) {
DuplicateHandle( GetCurrentProcess(), This->str.hf, GetCurrentProcess(),
&lpstr->str.hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
} else {
lpstr->str.lockbytes = This->str.lockbytes;
_ilockbytes16_addref(This->str.lockbytes);
}
MultiByteToWideChar( CP_ACP, 0, pwcsName, -1, name, sizeof(name)/sizeof(WCHAR));
newpps = STORAGE_look_for_named_pps(&lpstr->str,This->stde.pps_dir,name);
if (newpps==-1) {
IStream16_fnRelease((IStream16*)lpstr);
return E_FAIL;
}
if (1!=STORAGE_get_pps_entry(&lpstr->str,newpps,&(lpstr->stde))) {
IStream16_fnRelease((IStream16*)lpstr);
return E_FAIL;
}
lpstr->offset.u.LowPart = 0;
lpstr->offset.u.HighPart = 0;
lpstr->ppsent = newpps;
return S_OK;
}
/******************************************************************************
* _create_istorage16 [INTERNAL]
*/
static void _create_istorage16(LPSTORAGE16 *stg) {
IStorage16Impl* lpst;
if (!stvt16.QueryInterface) {
HMODULE16 wp = GetModuleHandle16("STORAGE");
if (wp>=32) {
#define VTENT(xfn) stvt16.xfn = (void*)GetProcAddress16(wp,"IStorage16_"#xfn);
VTENT(QueryInterface)
VTENT(AddRef)
VTENT(Release)
VTENT(CreateStream)
VTENT(OpenStream)
VTENT(CreateStorage)
VTENT(OpenStorage)
VTENT(CopyTo)
VTENT(MoveElementTo)
VTENT(Commit)
VTENT(Revert)
VTENT(EnumElements)
VTENT(DestroyElement)
VTENT(RenameElement)
VTENT(SetElementTimes)
VTENT(SetClass)
VTENT(SetStateBits)
VTENT(Stat)
#undef VTENT
segstvt16 = (const IStorage16Vtbl*)MapLS( &stvt16 );
} else {
#define VTENT(xfn) stvt16.xfn = IStorage16_fn##xfn;
VTENT(QueryInterface)
VTENT(AddRef)
VTENT(Release)
VTENT(CreateStream)
VTENT(OpenStream)
VTENT(CreateStorage)
VTENT(OpenStorage)
VTENT(CopyTo)
VTENT(Commit)
/* not (yet) implemented ...
VTENT(MoveElementTo)
VTENT(Revert)
VTENT(EnumElements)
VTENT(DestroyElement)
VTENT(RenameElement)
VTENT(SetElementTimes)
VTENT(SetClass)
VTENT(SetStateBits)
VTENT(Stat)
*/
#undef VTENT
segstvt16 = &stvt16;
}
}
lpst = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpst) );
lpst->lpVtbl = segstvt16;
lpst->str.hf = NULL;
lpst->str.lockbytes = 0;
lpst->ref = 1;
lpst->thisptr = MapLS(lpst);
*stg = (void*)lpst->thisptr;
}
/******************************************************************************
* Storage API functions
*/
/******************************************************************************
* StgCreateDocFileA [STORAGE.1]
*/
HRESULT WINAPI StgCreateDocFile16(
LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved,IStorage16 **ppstgOpen
) {
HANDLE hf;
int i,ret;
IStorage16Impl* lpstg;
struct storage_pps_entry stde;
TRACE("(%s,0x%08x,0x%08x,%p)\n",
pwcsName,grfMode,reserved,ppstgOpen
);
_create_istorage16(ppstgOpen);
hf = CreateFileA(pwcsName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,0);
if (hf==INVALID_HANDLE_VALUE) {
WARN("couldn't open file for storage:%d\n",GetLastError());
return E_FAIL;
}
lpstg = MapSL((SEGPT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -