Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregstream.c
Go to the documentation of this file.
00001 /* 00002 * SHLWAPI Registry Stream functions 00003 * 00004 * Copyright 1999 Juergen Schmied 00005 * Copyright 2002 Jon Griffiths 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include <stdarg.h> 00023 #include <string.h> 00024 00025 #define COBJMACROS 00026 00027 #include "winerror.h" 00028 #include "windef.h" 00029 #include "winbase.h" 00030 #include "objbase.h" 00031 #include "winreg.h" 00032 #include "shlwapi.h" 00033 00034 #include "wine/debug.h" 00035 00036 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00037 00038 typedef struct 00039 { 00040 const IStreamVtbl *lpVtbl; 00041 LONG ref; 00042 HKEY hKey; 00043 LPBYTE pbBuffer; 00044 DWORD dwLength; 00045 DWORD dwPos; 00046 DWORD dwMode; 00047 union { 00048 LPSTR keyNameA; 00049 LPWSTR keyNameW; 00050 }u; 00051 BOOL bUnicode; 00052 } ISHRegStream; 00053 00054 /************************************************************************** 00055 * IStream_fnQueryInterface 00056 */ 00057 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj) 00058 { 00059 ISHRegStream *This = (ISHRegStream *)iface; 00060 00061 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj); 00062 00063 *ppvObj = NULL; 00064 00065 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ 00066 *ppvObj = This; 00067 else if(IsEqualIID(riid, &IID_IStream)) /*IStream*/ 00068 *ppvObj = This; 00069 00070 if(*ppvObj) 00071 { 00072 IStream_AddRef((IStream*)*ppvObj); 00073 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); 00074 return S_OK; 00075 } 00076 TRACE("-- Interface: E_NOINTERFACE\n"); 00077 return E_NOINTERFACE; 00078 } 00079 00080 /************************************************************************** 00081 * IStream_fnAddRef 00082 */ 00083 static ULONG WINAPI IStream_fnAddRef(IStream *iface) 00084 { 00085 ISHRegStream *This = (ISHRegStream *)iface; 00086 ULONG refCount = InterlockedIncrement(&This->ref); 00087 00088 TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); 00089 00090 return refCount; 00091 } 00092 00093 /************************************************************************** 00094 * IStream_fnRelease 00095 */ 00096 static ULONG WINAPI IStream_fnRelease(IStream *iface) 00097 { 00098 ISHRegStream *This = (ISHRegStream *)iface; 00099 ULONG refCount = InterlockedDecrement(&This->ref); 00100 00101 TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); 00102 00103 if (!refCount) 00104 { 00105 TRACE(" destroying SHReg IStream (%p)\n",This); 00106 00107 if (This->hKey) 00108 { 00109 /* write back data in REG_BINARY */ 00110 if (This->dwMode == STGM_READWRITE || This->dwMode == STGM_WRITE) 00111 { 00112 if (This->dwLength) 00113 { 00114 if (This->bUnicode) 00115 RegSetValueExW(This->hKey, This->u.keyNameW, 0, REG_BINARY, 00116 (const BYTE *) This->pbBuffer, This->dwLength); 00117 else 00118 RegSetValueExA(This->hKey, This->u.keyNameA, 0, REG_BINARY, 00119 (const BYTE *) This->pbBuffer, This->dwLength); 00120 } 00121 else 00122 { 00123 if (This->bUnicode) 00124 RegDeleteValueW(This->hKey, This->u.keyNameW); 00125 else 00126 RegDeleteValueA(This->hKey, This->u.keyNameA); 00127 } 00128 } 00129 00130 RegCloseKey(This->hKey); 00131 } 00132 00133 HeapFree(GetProcessHeap(),0,This->u.keyNameA); 00134 HeapFree(GetProcessHeap(),0,This->pbBuffer); 00135 HeapFree(GetProcessHeap(),0,This); 00136 return 0; 00137 } 00138 00139 return refCount; 00140 } 00141 00142 /************************************************************************** 00143 * IStream_fnRead 00144 */ 00145 static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead) 00146 { 00147 ISHRegStream *This = (ISHRegStream *)iface; 00148 DWORD dwBytesToRead; 00149 00150 TRACE("(%p)->(%p,0x%08x,%p)\n",This, pv, cb, pcbRead); 00151 00152 if (This->dwPos >= This->dwLength) 00153 dwBytesToRead = 0; 00154 else 00155 dwBytesToRead = This->dwLength - This->dwPos; 00156 00157 dwBytesToRead = (cb > dwBytesToRead) ? dwBytesToRead : cb; 00158 if (dwBytesToRead != 0) /* not at end of buffer and we want to read something */ 00159 { 00160 memmove(pv, This->pbBuffer + This->dwPos, dwBytesToRead); 00161 This->dwPos += dwBytesToRead; /* adjust pointer */ 00162 } 00163 00164 if (pcbRead) 00165 *pcbRead = dwBytesToRead; 00166 00167 return S_OK; 00168 } 00169 00170 /************************************************************************** 00171 * IStream_fnWrite 00172 */ 00173 static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten) 00174 { 00175 ISHRegStream *This = (ISHRegStream *)iface; 00176 DWORD newLen = This->dwPos + cb; 00177 00178 TRACE("(%p, %p, %d, %p)\n",This, pv, cb, pcbWritten); 00179 00180 if (newLen < This->dwPos) /* overflow */ 00181 return STG_E_INSUFFICIENTMEMORY; 00182 00183 if (newLen > This->dwLength) 00184 { 00185 LPBYTE newBuf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pbBuffer, newLen); 00186 if (!newBuf) 00187 return STG_E_INSUFFICIENTMEMORY; 00188 00189 This->dwLength = newLen; 00190 This->pbBuffer = newBuf; 00191 } 00192 memmove(This->pbBuffer + This->dwPos, pv, cb); 00193 This->dwPos += cb; /* adjust pointer */ 00194 00195 if (pcbWritten) 00196 *pcbWritten = cb; 00197 00198 return S_OK; 00199 } 00200 00201 /************************************************************************** 00202 * IStream_fnSeek 00203 */ 00204 static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) 00205 { 00206 ISHRegStream *This = (ISHRegStream *)iface; 00207 LARGE_INTEGER tmp; 00208 TRACE("(%p, %s, %d %p)\n", This, 00209 wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); 00210 00211 if (dwOrigin == STREAM_SEEK_SET) 00212 tmp = dlibMove; 00213 else if (dwOrigin == STREAM_SEEK_CUR) 00214 tmp.QuadPart = This->dwPos + dlibMove.QuadPart; 00215 else if (dwOrigin == STREAM_SEEK_END) 00216 tmp.QuadPart = This->dwLength + dlibMove.QuadPart; 00217 else 00218 return STG_E_INVALIDPARAMETER; 00219 00220 if (tmp.QuadPart < 0) 00221 return STG_E_INVALIDFUNCTION; 00222 00223 /* we cut off the high part here */ 00224 This->dwPos = tmp.u.LowPart; 00225 00226 if (plibNewPosition) 00227 plibNewPosition->QuadPart = This->dwPos; 00228 return S_OK; 00229 } 00230 00231 /************************************************************************** 00232 * IStream_fnSetSize 00233 */ 00234 static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize) 00235 { 00236 ISHRegStream *This = (ISHRegStream *)iface; 00237 DWORD newLen; 00238 LPBYTE newBuf; 00239 00240 TRACE("(%p, %s)\n", This, wine_dbgstr_longlong(libNewSize.QuadPart)); 00241 00242 /* we cut off the high part here */ 00243 newLen = libNewSize.u.LowPart; 00244 newBuf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pbBuffer, newLen); 00245 if (!newBuf) 00246 return STG_E_INSUFFICIENTMEMORY; 00247 00248 This->pbBuffer = newBuf; 00249 This->dwLength = newLen; 00250 00251 return S_OK; 00252 } 00253 00254 /************************************************************************** 00255 * IStream_fnCopyTo 00256 */ 00257 static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) 00258 { 00259 ISHRegStream *This = (ISHRegStream *)iface; 00260 00261 TRACE("(%p)\n",This); 00262 if (pcbRead) 00263 pcbRead->QuadPart = 0; 00264 if (pcbWritten) 00265 pcbWritten->QuadPart = 0; 00266 00267 /* TODO implement */ 00268 return E_NOTIMPL; 00269 } 00270 00271 /************************************************************************** 00272 * IStream_fnCommit 00273 */ 00274 static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags) 00275 { 00276 ISHRegStream *This = (ISHRegStream *)iface; 00277 00278 TRACE("(%p)\n",This); 00279 00280 /* commit not supported by this stream */ 00281 return E_NOTIMPL; 00282 } 00283 00284 /************************************************************************** 00285 * IStream_fnRevert 00286 */ 00287 static HRESULT WINAPI IStream_fnRevert (IStream * iface) 00288 { 00289 ISHRegStream *This = (ISHRegStream *)iface; 00290 00291 TRACE("(%p)\n",This); 00292 00293 /* revert not supported by this stream */ 00294 return E_NOTIMPL; 00295 } 00296 00297 /************************************************************************** 00298 * IStream_fnLockUnlockRegion 00299 */ 00300 static HRESULT WINAPI IStream_fnLockUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) 00301 { 00302 ISHRegStream *This = (ISHRegStream *)iface; 00303 00304 TRACE("(%p)\n",This); 00305 00306 /* lock/unlock not supported by this stream */ 00307 return E_NOTIMPL; 00308 } 00309 00310 /************************************************************************* 00311 * IStream_fnStat 00312 */ 00313 static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag) 00314 { 00315 ISHRegStream *This = (ISHRegStream *)iface; 00316 00317 TRACE("(%p, %p, %d)\n",This,pstatstg,grfStatFlag); 00318 00319 pstatstg->pwcsName = NULL; 00320 pstatstg->type = STGTY_STREAM; 00321 pstatstg->cbSize.QuadPart = This->dwLength; 00322 pstatstg->mtime.dwHighDateTime = 0; 00323 pstatstg->mtime.dwLowDateTime = 0; 00324 pstatstg->ctime.dwHighDateTime = 0; 00325 pstatstg->ctime.dwLowDateTime = 0; 00326 pstatstg->atime.dwHighDateTime = 0; 00327 pstatstg->atime.dwLowDateTime = 0; 00328 pstatstg->grfMode = This->dwMode; 00329 pstatstg->grfLocksSupported = 0; 00330 pstatstg->clsid = CLSID_NULL; 00331 pstatstg->grfStateBits = 0; 00332 pstatstg->reserved = 0; 00333 00334 return S_OK; 00335 } 00336 00337 /************************************************************************* 00338 * IStream_fnClone 00339 */ 00340 static HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm) 00341 { 00342 ISHRegStream *This = (ISHRegStream *)iface; 00343 00344 TRACE("(%p)\n",This); 00345 *ppstm = NULL; 00346 00347 /* clone not supported by this stream */ 00348 return E_NOTIMPL; 00349 } 00350 00351 static const IStreamVtbl rstvt = 00352 { 00353 IStream_fnQueryInterface, 00354 IStream_fnAddRef, 00355 IStream_fnRelease, 00356 IStream_fnRead, 00357 IStream_fnWrite, 00358 IStream_fnSeek, 00359 IStream_fnSetSize, 00360 IStream_fnCopyTo, 00361 IStream_fnCommit, 00362 IStream_fnRevert, 00363 IStream_fnLockUnlockRegion, 00364 IStream_fnLockUnlockRegion, 00365 IStream_fnStat, 00366 IStream_fnClone 00367 }; 00368 00369 /* Methods overridden by the dummy stream */ 00370 00371 /************************************************************************** 00372 * IStream_fnAddRefDummy 00373 */ 00374 static ULONG WINAPI IStream_fnAddRefDummy(IStream *iface) 00375 { 00376 ISHRegStream *This = (ISHRegStream *)iface; 00377 TRACE("(%p)\n", This); 00378 return 2; 00379 } 00380 00381 /************************************************************************** 00382 * IStream_fnReleaseDummy 00383 */ 00384 static ULONG WINAPI IStream_fnReleaseDummy(IStream *iface) 00385 { 00386 ISHRegStream *This = (ISHRegStream *)iface; 00387 TRACE("(%p)\n", This); 00388 return 1; 00389 } 00390 00391 /************************************************************************** 00392 * IStream_fnReadDummy 00393 */ 00394 static HRESULT WINAPI IStream_fnReadDummy(IStream *iface, LPVOID pv, ULONG cb, ULONG* pcbRead) 00395 { 00396 if (pcbRead) 00397 *pcbRead = 0; 00398 return E_NOTIMPL; 00399 } 00400 00401 static const IStreamVtbl DummyRegStreamVTable = 00402 { 00403 IStream_fnQueryInterface, 00404 IStream_fnAddRefDummy, /* Overridden */ 00405 IStream_fnReleaseDummy, /* Overridden */ 00406 IStream_fnReadDummy, /* Overridden */ 00407 IStream_fnWrite, 00408 IStream_fnSeek, 00409 IStream_fnSetSize, 00410 IStream_fnCopyTo, 00411 IStream_fnCommit, 00412 IStream_fnRevert, 00413 IStream_fnLockUnlockRegion, 00414 IStream_fnLockUnlockRegion, 00415 IStream_fnStat, 00416 IStream_fnClone 00417 }; 00418 00419 /* Dummy registry stream object */ 00420 static ISHRegStream rsDummyRegStream = 00421 { 00422 &DummyRegStreamVTable, 00423 1, 00424 NULL, 00425 NULL, 00426 0, 00427 0, 00428 STGM_READWRITE, 00429 {NULL}, 00430 FALSE 00431 }; 00432 00433 /************************************************************************** 00434 * IStream_Create 00435 * 00436 * Internal helper: Create and initialise a new registry stream object. 00437 */ 00438 static ISHRegStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) 00439 { 00440 ISHRegStream* regStream; 00441 00442 regStream = HeapAlloc(GetProcessHeap(), 0, sizeof(ISHRegStream)); 00443 00444 if (regStream) 00445 { 00446 regStream->lpVtbl = &rstvt; 00447 regStream->ref = 1; 00448 regStream->hKey = hKey; 00449 regStream->pbBuffer = pbBuffer; 00450 regStream->dwLength = dwLength; 00451 regStream->dwPos = 0; 00452 regStream->dwMode = STGM_READWRITE; 00453 regStream->u.keyNameA = NULL; 00454 regStream->bUnicode = FALSE; 00455 } 00456 TRACE ("Returning %p\n", regStream); 00457 return regStream; 00458 } 00459 00460 /************************************************************************* 00461 * SHOpenRegStream2A [SHLWAPI.@] 00462 * 00463 * Create a stream to read binary registry data. 00464 * 00465 * PARAMS 00466 * hKey [I] Registry handle 00467 * pszSubkey [I] The sub key name 00468 * pszValue [I] The value name under the sub key 00469 * dwMode [I] Unused 00470 * 00471 * RETURNS 00472 * Success: An IStream interface referring to the registry data 00473 * Failure: NULL, if the registry key could not be opened or is not binary. 00474 */ 00475 IStream * WINAPI SHOpenRegStream2A(HKEY hKey, LPCSTR pszSubkey, 00476 LPCSTR pszValue,DWORD dwMode) 00477 { 00478 ISHRegStream *tmp; 00479 HKEY hStrKey = NULL; 00480 LPBYTE lpBuff = NULL; 00481 DWORD dwLength = 0; 00482 LONG ret; 00483 00484 TRACE("(%p,%s,%s,0x%08x)\n", hKey, pszSubkey, pszValue, dwMode); 00485 00486 if (dwMode == STGM_READ) 00487 ret = RegOpenKeyExA(hKey, pszSubkey, 0, KEY_READ, &hStrKey); 00488 else /* in write mode we make sure the subkey exits */ 00489 ret = RegCreateKeyExA(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); 00490 00491 if (ret == ERROR_SUCCESS) 00492 { 00493 if (dwMode == STGM_READ || dwMode == STGM_READWRITE) 00494 { 00495 /* read initial data */ 00496 ret = RegQueryValueExA(hStrKey, pszValue, 0, 0, 0, &dwLength); 00497 if (ret == ERROR_SUCCESS && dwLength) 00498 { 00499 lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); 00500 RegQueryValueExA(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); 00501 } 00502 } 00503 00504 if (!dwLength) 00505 lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); 00506 00507 tmp = IStream_Create(hStrKey, lpBuff, dwLength); 00508 if(tmp) 00509 { 00510 if(pszValue) 00511 { 00512 int len = lstrlenA(pszValue) + 1; 00513 tmp->u.keyNameA = HeapAlloc(GetProcessHeap(), 0, len); 00514 memcpy(tmp->u.keyNameA, pszValue, len); 00515 } 00516 00517 tmp->dwMode = dwMode; 00518 tmp->bUnicode = FALSE; 00519 return (IStream *)tmp; 00520 } 00521 } 00522 00523 HeapFree(GetProcessHeap(), 0, lpBuff); 00524 if (hStrKey) 00525 RegCloseKey(hStrKey); 00526 return NULL; 00527 } 00528 00529 /************************************************************************* 00530 * SHOpenRegStream2W [SHLWAPI.@] 00531 * 00532 * See SHOpenRegStream2A. 00533 */ 00534 IStream * WINAPI SHOpenRegStream2W(HKEY hKey, LPCWSTR pszSubkey, 00535 LPCWSTR pszValue, DWORD dwMode) 00536 { 00537 ISHRegStream *tmp; 00538 HKEY hStrKey = NULL; 00539 LPBYTE lpBuff = NULL; 00540 DWORD dwLength = 0; 00541 LONG ret; 00542 00543 TRACE("(%p,%s,%s,0x%08x)\n", hKey, debugstr_w(pszSubkey), 00544 debugstr_w(pszValue), dwMode); 00545 00546 if (dwMode == STGM_READ) 00547 ret = RegOpenKeyExW(hKey, pszSubkey, 0, KEY_READ, &hStrKey); 00548 else /* in write mode we make sure the subkey exits */ 00549 ret = RegCreateKeyExW(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); 00550 00551 if (ret == ERROR_SUCCESS) 00552 { 00553 if (dwMode == STGM_READ || dwMode == STGM_READWRITE) 00554 { 00555 /* read initial data */ 00556 ret = RegQueryValueExW(hStrKey, pszValue, 0, 0, 0, &dwLength); 00557 if (ret == ERROR_SUCCESS && dwLength) 00558 { 00559 lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); 00560 RegQueryValueExW(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); 00561 } 00562 } 00563 00564 if (!dwLength) 00565 lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); 00566 00567 tmp = IStream_Create(hStrKey, lpBuff, dwLength); 00568 if(tmp) 00569 { 00570 if(pszValue) 00571 { 00572 int len = lstrlenW(pszValue) + 1; 00573 tmp->u.keyNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00574 memcpy(tmp->u.keyNameW, pszValue, len * sizeof(WCHAR)); 00575 } 00576 00577 tmp->dwMode = dwMode; 00578 tmp->bUnicode = TRUE; 00579 return (IStream *)tmp; 00580 } 00581 } 00582 00583 HeapFree(GetProcessHeap(), 0, lpBuff); 00584 if (hStrKey) 00585 RegCloseKey(hStrKey); 00586 return NULL; 00587 } 00588 00589 /************************************************************************* 00590 * SHOpenRegStreamA [SHLWAPI.@] 00591 * 00592 * Create a stream to read binary registry data. 00593 * 00594 * PARAMS 00595 * hKey [I] Registry handle 00596 * pszSubkey [I] The sub key name 00597 * pszValue [I] The value name under the sub key 00598 * dwMode [I] STGM mode for opening the file 00599 * 00600 * RETURNS 00601 * Success: An IStream interface referring to the registry data 00602 * Failure: If the registry key could not be opened or is not binary, 00603 * A dummy (empty) IStream object is returned. 00604 */ 00605 IStream * WINAPI SHOpenRegStreamA(HKEY hkey, LPCSTR pszSubkey, 00606 LPCSTR pszValue, DWORD dwMode) 00607 { 00608 IStream *iStream; 00609 00610 TRACE("(%p,%s,%s,0x%08x)\n", hkey, pszSubkey, pszValue, dwMode); 00611 00612 iStream = SHOpenRegStream2A(hkey, pszSubkey, pszValue, dwMode); 00613 return iStream ? iStream : (IStream *)&rsDummyRegStream; 00614 } 00615 00616 /************************************************************************* 00617 * SHOpenRegStreamW [SHLWAPI.@] 00618 * 00619 * See SHOpenRegStreamA. 00620 */ 00621 IStream * WINAPI SHOpenRegStreamW(HKEY hkey, LPCWSTR pszSubkey, 00622 LPCWSTR pszValue, DWORD dwMode) 00623 { 00624 IStream *iStream; 00625 00626 TRACE("(%p,%s,%s,0x%08x)\n", hkey, debugstr_w(pszSubkey), 00627 debugstr_w(pszValue), dwMode); 00628 iStream = SHOpenRegStream2W(hkey, pszSubkey, pszValue, dwMode); 00629 return iStream ? iStream : (IStream *)&rsDummyRegStream; 00630 } 00631 00632 /************************************************************************* 00633 * @ [SHLWAPI.12] 00634 * 00635 * Create an IStream object on a block of memory. 00636 * 00637 * PARAMS 00638 * lpbData [I] Memory block to create the IStream object on 00639 * dwDataLen [I] Length of data block 00640 * 00641 * RETURNS 00642 * Success: A pointer to the IStream object. 00643 * Failure: NULL, if any parameters are invalid or an error occurs. 00644 * 00645 * NOTES 00646 * A copy of the memory pointed to by lpbData is made, and is freed 00647 * when the stream is released. 00648 */ 00649 IStream * WINAPI SHCreateMemStream(const BYTE *lpbData, UINT dwDataLen) 00650 { 00651 IStream *iStrmRet = NULL; 00652 LPBYTE lpbDup; 00653 00654 TRACE("(%p,%d)\n", lpbData, dwDataLen); 00655 00656 if (!lpbData) 00657 dwDataLen = 0; 00658 00659 lpbDup = HeapAlloc(GetProcessHeap(), 0, dwDataLen); 00660 00661 if (lpbDup) 00662 { 00663 memcpy(lpbDup, lpbData, dwDataLen); 00664 iStrmRet = (IStream *)IStream_Create(NULL, lpbDup, dwDataLen); 00665 00666 if (!iStrmRet) 00667 HeapFree(GetProcessHeap(), 0, lpbDup); 00668 } 00669 return iStrmRet; 00670 } 00671 00672 /************************************************************************* 00673 * SHCreateStreamWrapper [SHLWAPI.@] 00674 * 00675 * Create an IStream object on a block of memory. 00676 * 00677 * PARAMS 00678 * lpbData [I] Memory block to create the IStream object on 00679 * dwDataLen [I] Length of data block 00680 * dwReserved [I] Reserved, Must be 0. 00681 * lppStream [O] Destination for IStream object 00682 * 00683 * RETURNS 00684 * Success: S_OK. lppStream contains the new IStream object. 00685 * Failure: E_INVALIDARG, if any parameters are invalid, 00686 * E_OUTOFMEMORY if memory allocation fails. 00687 * 00688 * NOTES 00689 * The stream assumes ownership of the memory passed to it. 00690 */ 00691 HRESULT WINAPI SHCreateStreamWrapper(LPBYTE lpbData, DWORD dwDataLen, 00692 DWORD dwReserved, IStream **lppStream) 00693 { 00694 IStream* lpStream; 00695 00696 if (lppStream) 00697 *lppStream = NULL; 00698 00699 if(dwReserved || !lppStream) 00700 return E_INVALIDARG; 00701 00702 lpStream = (IStream *)IStream_Create(NULL, lpbData, dwDataLen); 00703 00704 if(!lpStream) 00705 return E_OUTOFMEMORY; 00706 00707 IStream_QueryInterface(lpStream, &IID_IStream, (void**)lppStream); 00708 IStream_Release(lpStream); 00709 return S_OK; 00710 } Generated on Sat May 26 2012 04:25:07 for ReactOS by
1.7.6.1
|