Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenordinal.c
Go to the documentation of this file.
00001 /* 00002 * SHLWAPI ordinal functions 00003 * 00004 * Copyright 1997 Marcus Meissner 00005 * 1998 Jürgen Schmied 00006 * 2001-2003 Jon Griffiths 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 00023 #include "config.h" 00024 #include "wine/port.h" 00025 00026 #include <stdarg.h> 00027 #include <stdio.h> 00028 #include <string.h> 00029 00030 #define COBJMACROS 00031 #define NONAMELESSUNION 00032 #define NONAMELESSSTRUCT 00033 00034 #include "windef.h" 00035 #include "winbase.h" 00036 #include "winnls.h" 00037 #include "winreg.h" 00038 #include "wingdi.h" 00039 #include "winuser.h" 00040 #include "winver.h" 00041 #include "winnetwk.h" 00042 #include "mmsystem.h" 00043 #include "objbase.h" 00044 #include "exdisp.h" 00045 #include "shdeprecated.h" 00046 #include "shlobj.h" 00047 #include "shlwapi.h" 00048 #include "shellapi.h" 00049 #include "commdlg.h" 00050 #include "mlang.h" 00051 #include "mshtmhst.h" 00052 #include "wine/unicode.h" 00053 #include "wine/debug.h" 00054 00055 00056 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00057 00058 /* DLL handles for late bound calls */ 00059 extern HINSTANCE shlwapi_hInstance; 00060 extern DWORD SHLWAPI_ThreadRef_index; 00061 00062 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*); 00063 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL); 00064 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD); 00065 00066 /* 00067 NOTES: Most functions exported by ordinal seem to be superfluous. 00068 The reason for these functions to be there is to provide a wrapper 00069 for unicode functions to provide these functions on systems without 00070 unicode functions eg. win95/win98. Since we have such functions we just 00071 call these. If running Wine with native DLLs, some late bound calls may 00072 fail. However, it is better to implement the functions in the forward DLL 00073 and recommend the builtin rather than reimplementing the calls here! 00074 */ 00075 00076 /************************************************************************* 00077 * SHLWAPI_DupSharedHandle 00078 * 00079 * Internal implemetation of SHLWAPI_11. 00080 */ 00081 static HANDLE SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId, 00082 DWORD dwSrcProcId, DWORD dwAccess, 00083 DWORD dwOptions) 00084 { 00085 HANDLE hDst, hSrc; 00086 DWORD dwMyProcId = GetCurrentProcessId(); 00087 HANDLE hRet = NULL; 00088 00089 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared, dwDstProcId, dwSrcProcId, 00090 dwAccess, dwOptions); 00091 00092 /* Get dest process handle */ 00093 if (dwDstProcId == dwMyProcId) 00094 hDst = GetCurrentProcess(); 00095 else 00096 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId); 00097 00098 if (hDst) 00099 { 00100 /* Get src process handle */ 00101 if (dwSrcProcId == dwMyProcId) 00102 hSrc = GetCurrentProcess(); 00103 else 00104 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId); 00105 00106 if (hSrc) 00107 { 00108 /* Make handle available to dest process */ 00109 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet, 00110 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS)) 00111 hRet = NULL; 00112 00113 if (dwSrcProcId != dwMyProcId) 00114 CloseHandle(hSrc); 00115 } 00116 00117 if (dwDstProcId != dwMyProcId) 00118 CloseHandle(hDst); 00119 } 00120 00121 TRACE("Returning handle %p\n", hRet); 00122 return hRet; 00123 } 00124 00125 /************************************************************************* 00126 * @ [SHLWAPI.7] 00127 * 00128 * Create a block of sharable memory and initialise it with data. 00129 * 00130 * PARAMS 00131 * lpvData [I] Pointer to data to write 00132 * dwSize [I] Size of data 00133 * dwProcId [I] ID of process owning data 00134 * 00135 * RETURNS 00136 * Success: A shared memory handle 00137 * Failure: NULL 00138 * 00139 * NOTES 00140 * Ordinals 7-11 provide a set of calls to create shared memory between a 00141 * group of processes. The shared memory is treated opaquely in that its size 00142 * is not exposed to clients who map it. This is accomplished by storing 00143 * the size of the map as the first DWORD of mapped data, and then offsetting 00144 * the view pointer returned by this size. 00145 * 00146 */ 00147 HANDLE WINAPI SHAllocShared(LPVOID lpvData, ULONG dwSize, DWORD dwProcId) 00148 { 00149 HANDLE hMap; 00150 LPVOID pMapped; 00151 HANDLE hRet = NULL; 00152 00153 TRACE("(%p,%d,%d)\n", lpvData, dwSize, dwProcId); 00154 00155 /* Create file mapping of the correct length */ 00156 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0, 00157 dwSize + sizeof(dwSize), NULL); 00158 if (!hMap) 00159 return hRet; 00160 00161 /* Get a view in our process address space */ 00162 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 00163 00164 if (pMapped) 00165 { 00166 /* Write size of data, followed by the data, to the view */ 00167 *((DWORD*)pMapped) = dwSize; 00168 if (lpvData) 00169 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize); 00170 00171 /* Release view. All further views mapped will be opaque */ 00172 UnmapViewOfFile(pMapped); 00173 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId, 00174 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS, 00175 DUPLICATE_SAME_ACCESS); 00176 } 00177 00178 CloseHandle(hMap); 00179 return hRet; 00180 } 00181 00182 /************************************************************************* 00183 * @ [SHLWAPI.8] 00184 * 00185 * Get a pointer to a block of shared memory from a shared memory handle. 00186 * 00187 * PARAMS 00188 * hShared [I] Shared memory handle 00189 * dwProcId [I] ID of process owning hShared 00190 * 00191 * RETURNS 00192 * Success: A pointer to the shared memory 00193 * Failure: NULL 00194 * 00195 */ 00196 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId) 00197 { 00198 HANDLE hDup; 00199 LPVOID pMapped; 00200 00201 TRACE("(%p %d)\n", hShared, dwProcId); 00202 00203 /* Get handle to shared memory for current process */ 00204 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(), 00205 FILE_MAP_ALL_ACCESS, 0); 00206 /* Get View */ 00207 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 00208 CloseHandle(hDup); 00209 00210 if (pMapped) 00211 return (char *) pMapped + sizeof(DWORD); /* Hide size */ 00212 return NULL; 00213 } 00214 00215 /************************************************************************* 00216 * @ [SHLWAPI.9] 00217 * 00218 * Release a pointer to a block of shared memory. 00219 * 00220 * PARAMS 00221 * lpView [I] Shared memory pointer 00222 * 00223 * RETURNS 00224 * Success: TRUE 00225 * Failure: FALSE 00226 * 00227 */ 00228 BOOL WINAPI SHUnlockShared(LPVOID lpView) 00229 { 00230 TRACE("(%p)\n", lpView); 00231 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */ 00232 } 00233 00234 /************************************************************************* 00235 * @ [SHLWAPI.10] 00236 * 00237 * Destroy a block of sharable memory. 00238 * 00239 * PARAMS 00240 * hShared [I] Shared memory handle 00241 * dwProcId [I] ID of process owning hShared 00242 * 00243 * RETURNS 00244 * Success: TRUE 00245 * Failure: FALSE 00246 * 00247 */ 00248 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId) 00249 { 00250 HANDLE hClose; 00251 00252 TRACE("(%p %d)\n", hShared, dwProcId); 00253 00254 /* Get a copy of the handle for our process, closing the source handle */ 00255 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(), 00256 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE); 00257 /* Close local copy */ 00258 return CloseHandle(hClose); 00259 } 00260 00261 /************************************************************************* 00262 * @ [SHLWAPI.11] 00263 * 00264 * Copy a sharable memory handle from one process to another. 00265 * 00266 * PARAMS 00267 * hShared [I] Shared memory handle to duplicate 00268 * dwDstProcId [I] ID of the process wanting the duplicated handle 00269 * dwSrcProcId [I] ID of the process owning hShared 00270 * dwAccess [I] Desired DuplicateHandle() access 00271 * dwOptions [I] Desired DuplicateHandle() options 00272 * 00273 * RETURNS 00274 * Success: A handle suitable for use by the dwDstProcId process. 00275 * Failure: A NULL handle. 00276 * 00277 */ 00278 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId, 00279 DWORD dwAccess, DWORD dwOptions) 00280 { 00281 HANDLE hRet; 00282 00283 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId, 00284 dwAccess, dwOptions); 00285 return hRet; 00286 } 00287 00288 /************************************************************************* 00289 * @ [SHLWAPI.13] 00290 * 00291 * Create and register a clipboard enumerator for a web browser. 00292 * 00293 * PARAMS 00294 * lpBC [I] Binding context 00295 * lpUnknown [I] An object exposing the IWebBrowserApp interface 00296 * 00297 * RETURNS 00298 * Success: S_OK. 00299 * Failure: An HRESULT error code. 00300 * 00301 * NOTES 00302 * The enumerator is stored as a property of the web browser. If it does not 00303 * yet exist, it is created and set before being registered. 00304 */ 00305 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) 00306 { 00307 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0', 00308 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0', 00309 '0','A','A','0','0','4','A','E','8','3','7','}','\0' }; 00310 BSTR property; 00311 IEnumFORMATETC* pIEnumFormatEtc = NULL; 00312 VARIANTARG var; 00313 HRESULT hr; 00314 IWebBrowserApp* pBrowser; 00315 00316 TRACE("(%p, %p)\n", lpBC, lpUnknown); 00317 00318 hr = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (void**)&pBrowser); 00319 if (FAILED(hr)) 00320 return hr; 00321 00322 V_VT(&var) = VT_EMPTY; 00323 00324 /* The property we get is the browsers clipboard enumerator */ 00325 property = SysAllocString(szProperty); 00326 hr = IWebBrowserApp_GetProperty(pBrowser, property, &var); 00327 SysFreeString(property); 00328 if (FAILED(hr)) goto exit; 00329 00330 if (V_VT(&var) == VT_EMPTY) 00331 { 00332 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */ 00333 char szKeyBuff[128], szValueBuff[128]; 00334 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType; 00335 FORMATETC* formatList, *format; 00336 HKEY hDocs; 00337 00338 TRACE("Registering formats and creating IEnumFORMATETC instance\n"); 00339 00340 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current" 00341 "Version\\Internet Settings\\Accepted Documents", &hDocs)) 00342 { 00343 hr = E_FAIL; 00344 goto exit; 00345 } 00346 00347 /* Get count of values in key */ 00348 while (!dwRet) 00349 { 00350 dwKeySize = sizeof(szKeyBuff); 00351 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0); 00352 dwCount++; 00353 } 00354 00355 dwNumValues = dwCount; 00356 00357 /* Note: dwCount = number of items + 1; The extra item is the end node */ 00358 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC)); 00359 if (!formatList) 00360 { 00361 RegCloseKey(hDocs); 00362 hr = E_OUTOFMEMORY; 00363 goto exit; 00364 } 00365 00366 if (dwNumValues > 1) 00367 { 00368 dwRet = 0; 00369 dwCount = 0; 00370 00371 dwNumValues--; 00372 00373 /* Register clipboard formats for the values and populate format list */ 00374 while(!dwRet && dwCount < dwNumValues) 00375 { 00376 dwKeySize = sizeof(szKeyBuff); 00377 dwValueSize = sizeof(szValueBuff); 00378 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType, 00379 (PBYTE)szValueBuff, &dwValueSize); 00380 if (!dwRet) 00381 { 00382 HeapFree(GetProcessHeap(), 0, formatList); 00383 RegCloseKey(hDocs); 00384 hr = E_FAIL; 00385 goto exit; 00386 } 00387 00388 format->cfFormat = RegisterClipboardFormatA(szValueBuff); 00389 format->ptd = NULL; 00390 format->dwAspect = 1; 00391 format->lindex = 4; 00392 format->tymed = -1; 00393 00394 format++; 00395 dwCount++; 00396 } 00397 } 00398 00399 RegCloseKey(hDocs); 00400 00401 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */ 00402 format->cfFormat = 0; 00403 format->ptd = NULL; 00404 format->dwAspect = 1; 00405 format->lindex = 4; 00406 format->tymed = -1; 00407 00408 /* Create a clipboard enumerator */ 00409 hr = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc); 00410 HeapFree(GetProcessHeap(), 0, formatList); 00411 if (FAILED(hr)) goto exit; 00412 00413 /* Set our enumerator as the browsers property */ 00414 V_VT(&var) = VT_UNKNOWN; 00415 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc; 00416 00417 property = SysAllocString(szProperty); 00418 hr = IWebBrowserApp_PutProperty(pBrowser, property, var); 00419 SysFreeString(property); 00420 if (FAILED(hr)) 00421 { 00422 IEnumFORMATETC_Release(pIEnumFormatEtc); 00423 goto exit; 00424 } 00425 } 00426 00427 if (V_VT(&var) == VT_UNKNOWN) 00428 { 00429 /* Our variant is holding the clipboard enumerator */ 00430 IUnknown* pIUnknown = V_UNKNOWN(&var); 00431 IEnumFORMATETC* pClone = NULL; 00432 00433 TRACE("Retrieved IEnumFORMATETC property\n"); 00434 00435 /* Get an IEnumFormatEtc interface from the variants value */ 00436 pIEnumFormatEtc = NULL; 00437 hr = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC, (void**)&pIEnumFormatEtc); 00438 if (hr == S_OK && pIEnumFormatEtc) 00439 { 00440 /* Clone and register the enumerator */ 00441 hr = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone); 00442 if (hr == S_OK && pClone) 00443 { 00444 RegisterFormatEnumerator(lpBC, pClone, 0); 00445 00446 IEnumFORMATETC_Release(pClone); 00447 } 00448 00449 IEnumFORMATETC_Release(pIUnknown); 00450 } 00451 IUnknown_Release(V_UNKNOWN(&var)); 00452 } 00453 00454 exit: 00455 IWebBrowserApp_Release(pBrowser); 00456 return hr; 00457 } 00458 00459 /************************************************************************* 00460 * @ [SHLWAPI.15] 00461 * 00462 * Get Explorers "AcceptLanguage" setting. 00463 * 00464 * PARAMS 00465 * langbuf [O] Destination for language string 00466 * buflen [I] Length of langbuf in characters 00467 * [0] Success: used length of langbuf 00468 * 00469 * RETURNS 00470 * Success: S_OK. langbuf is set to the language string found. 00471 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer 00472 * does not contain the setting. 00473 * HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), If the buffer is not big enough 00474 */ 00475 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) 00476 { 00477 static const WCHAR szkeyW[] = { 00478 'S','o','f','t','w','a','r','e','\\', 00479 'M','i','c','r','o','s','o','f','t','\\', 00480 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\', 00481 'I','n','t','e','r','n','a','t','i','o','n','a','l',0}; 00482 static const WCHAR valueW[] = { 00483 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0}; 00484 DWORD mystrlen, mytype; 00485 DWORD len; 00486 HKEY mykey; 00487 LCID mylcid; 00488 WCHAR *mystr; 00489 LONG lres; 00490 00491 TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1); 00492 00493 if(!langbuf || !buflen || !*buflen) 00494 return E_FAIL; 00495 00496 mystrlen = (*buflen > 20) ? *buflen : 20 ; 00497 len = mystrlen * sizeof(WCHAR); 00498 mystr = HeapAlloc(GetProcessHeap(), 0, len); 00499 mystr[0] = 0; 00500 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey); 00501 lres = RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &len); 00502 RegCloseKey(mykey); 00503 len = lstrlenW(mystr); 00504 00505 if (!lres && (*buflen > len)) { 00506 lstrcpyW(langbuf, mystr); 00507 *buflen = len; 00508 HeapFree(GetProcessHeap(), 0, mystr); 00509 return S_OK; 00510 } 00511 00512 /* Did not find a value in the registry or the user buffer is too small */ 00513 mylcid = GetUserDefaultLCID(); 00514 LcidToRfc1766W(mylcid, mystr, mystrlen); 00515 len = lstrlenW(mystr); 00516 00517 memcpy( langbuf, mystr, min(*buflen, len+1)*sizeof(WCHAR) ); 00518 HeapFree(GetProcessHeap(), 0, mystr); 00519 00520 if (*buflen > len) { 00521 *buflen = len; 00522 return S_OK; 00523 } 00524 00525 *buflen = 0; 00526 return __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00527 } 00528 00529 /************************************************************************* 00530 * @ [SHLWAPI.14] 00531 * 00532 * Ascii version of GetAcceptLanguagesW. 00533 */ 00534 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen) 00535 { 00536 WCHAR *langbufW; 00537 DWORD buflenW, convlen; 00538 HRESULT retval; 00539 00540 TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1); 00541 00542 if(!langbuf || !buflen || !*buflen) return E_FAIL; 00543 00544 buflenW = *buflen; 00545 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW); 00546 retval = GetAcceptLanguagesW(langbufW, &buflenW); 00547 00548 if (retval == S_OK) 00549 { 00550 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, *buflen, NULL, NULL); 00551 convlen--; /* do not count the terminating 0 */ 00552 } 00553 else /* copy partial string anyway */ 00554 { 00555 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, *buflen, langbuf, *buflen, NULL, NULL); 00556 if (convlen < *buflen) 00557 { 00558 langbuf[convlen] = 0; 00559 convlen--; /* do not count the terminating 0 */ 00560 } 00561 else 00562 { 00563 convlen = *buflen; 00564 } 00565 } 00566 *buflen = buflenW ? convlen : 0; 00567 00568 HeapFree(GetProcessHeap(), 0, langbufW); 00569 return retval; 00570 } 00571 00572 /************************************************************************* 00573 * @ [SHLWAPI.23] 00574 * 00575 * Convert a GUID to a string. 00576 * 00577 * PARAMS 00578 * guid [I] GUID to convert 00579 * lpszDest [O] Destination for string 00580 * cchMax [I] Length of output buffer 00581 * 00582 * RETURNS 00583 * The length of the string created. 00584 */ 00585 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax) 00586 { 00587 char xguid[40]; 00588 INT iLen; 00589 00590 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax); 00591 00592 sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 00593 guid->Data1, guid->Data2, guid->Data3, 00594 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], 00595 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); 00596 00597 iLen = strlen(xguid) + 1; 00598 00599 if (iLen > cchMax) 00600 return 0; 00601 memcpy(lpszDest, xguid, iLen); 00602 return iLen; 00603 } 00604 00605 /************************************************************************* 00606 * @ [SHLWAPI.24] 00607 * 00608 * Convert a GUID to a string. 00609 * 00610 * PARAMS 00611 * guid [I] GUID to convert 00612 * str [O] Destination for string 00613 * cmax [I] Length of output buffer 00614 * 00615 * RETURNS 00616 * The length of the string created. 00617 */ 00618 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax) 00619 { 00620 WCHAR xguid[40]; 00621 INT iLen; 00622 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-', 00623 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2', 00624 'X','%','0','2','X','%','0','2','X','}',0}; 00625 00626 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax); 00627 00628 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3, 00629 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], 00630 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); 00631 00632 iLen = strlenW(xguid) + 1; 00633 00634 if (iLen > cchMax) 00635 return 0; 00636 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR)); 00637 return iLen; 00638 } 00639 00640 /************************************************************************* 00641 * @ [SHLWAPI.29] 00642 * 00643 * Determine if a Unicode character is a space. 00644 * 00645 * PARAMS 00646 * wc [I] Character to check. 00647 * 00648 * RETURNS 00649 * TRUE, if wc is a space, 00650 * FALSE otherwise. 00651 */ 00652 BOOL WINAPI IsCharSpaceW(WCHAR wc) 00653 { 00654 WORD CharType; 00655 00656 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE); 00657 } 00658 00659 /************************************************************************* 00660 * @ [SHLWAPI.30] 00661 * 00662 * Determine if a Unicode character is a blank. 00663 * 00664 * PARAMS 00665 * wc [I] Character to check. 00666 * 00667 * RETURNS 00668 * TRUE, if wc is a blank, 00669 * FALSE otherwise. 00670 * 00671 */ 00672 BOOL WINAPI IsCharBlankW(WCHAR wc) 00673 { 00674 WORD CharType; 00675 00676 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK); 00677 } 00678 00679 /************************************************************************* 00680 * @ [SHLWAPI.31] 00681 * 00682 * Determine if a Unicode character is punctuation. 00683 * 00684 * PARAMS 00685 * wc [I] Character to check. 00686 * 00687 * RETURNS 00688 * TRUE, if wc is punctuation, 00689 * FALSE otherwise. 00690 */ 00691 BOOL WINAPI IsCharPunctW(WCHAR wc) 00692 { 00693 WORD CharType; 00694 00695 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT); 00696 } 00697 00698 /************************************************************************* 00699 * @ [SHLWAPI.32] 00700 * 00701 * Determine if a Unicode character is a control character. 00702 * 00703 * PARAMS 00704 * wc [I] Character to check. 00705 * 00706 * RETURNS 00707 * TRUE, if wc is a control character, 00708 * FALSE otherwise. 00709 */ 00710 BOOL WINAPI IsCharCntrlW(WCHAR wc) 00711 { 00712 WORD CharType; 00713 00714 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL); 00715 } 00716 00717 /************************************************************************* 00718 * @ [SHLWAPI.33] 00719 * 00720 * Determine if a Unicode character is a digit. 00721 * 00722 * PARAMS 00723 * wc [I] Character to check. 00724 * 00725 * RETURNS 00726 * TRUE, if wc is a digit, 00727 * FALSE otherwise. 00728 */ 00729 BOOL WINAPI IsCharDigitW(WCHAR wc) 00730 { 00731 WORD CharType; 00732 00733 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT); 00734 } 00735 00736 /************************************************************************* 00737 * @ [SHLWAPI.34] 00738 * 00739 * Determine if a Unicode character is a hex digit. 00740 * 00741 * PARAMS 00742 * wc [I] Character to check. 00743 * 00744 * RETURNS 00745 * TRUE, if wc is a hex digit, 00746 * FALSE otherwise. 00747 */ 00748 BOOL WINAPI IsCharXDigitW(WCHAR wc) 00749 { 00750 WORD CharType; 00751 00752 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT); 00753 } 00754 00755 /************************************************************************* 00756 * @ [SHLWAPI.35] 00757 * 00758 */ 00759 BOOL WINAPI GetStringType3ExW(LPWSTR src, INT count, LPWORD type) 00760 { 00761 return GetStringTypeW(CT_CTYPE3, src, count, type); 00762 } 00763 00764 /************************************************************************* 00765 * @ [SHLWAPI.151] 00766 * 00767 * Compare two Ascii strings up to a given length. 00768 * 00769 * PARAMS 00770 * lpszSrc [I] Source string 00771 * lpszCmp [I] String to compare to lpszSrc 00772 * len [I] Maximum length 00773 * 00774 * RETURNS 00775 * A number greater than, less than or equal to 0 depending on whether 00776 * lpszSrc is greater than, less than or equal to lpszCmp. 00777 */ 00778 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len) 00779 { 00780 return StrCmpNA(lpszSrc, lpszCmp, len); 00781 } 00782 00783 /************************************************************************* 00784 * @ [SHLWAPI.152] 00785 * 00786 * Unicode version of StrCmpNCA. 00787 */ 00788 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len) 00789 { 00790 return StrCmpNW(lpszSrc, lpszCmp, len); 00791 } 00792 00793 /************************************************************************* 00794 * @ [SHLWAPI.153] 00795 * 00796 * Compare two Ascii strings up to a given length, ignoring case. 00797 * 00798 * PARAMS 00799 * lpszSrc [I] Source string 00800 * lpszCmp [I] String to compare to lpszSrc 00801 * len [I] Maximum length 00802 * 00803 * RETURNS 00804 * A number greater than, less than or equal to 0 depending on whether 00805 * lpszSrc is greater than, less than or equal to lpszCmp. 00806 */ 00807 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len) 00808 { 00809 return StrCmpNIA(lpszSrc, lpszCmp, len); 00810 } 00811 00812 /************************************************************************* 00813 * @ [SHLWAPI.154] 00814 * 00815 * Unicode version of StrCmpNICA. 00816 */ 00817 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len) 00818 { 00819 return StrCmpNIW(lpszSrc, lpszCmp, len); 00820 } 00821 00822 /************************************************************************* 00823 * @ [SHLWAPI.155] 00824 * 00825 * Compare two Ascii strings. 00826 * 00827 * PARAMS 00828 * lpszSrc [I] Source string 00829 * lpszCmp [I] String to compare to lpszSrc 00830 * 00831 * RETURNS 00832 * A number greater than, less than or equal to 0 depending on whether 00833 * lpszSrc is greater than, less than or equal to lpszCmp. 00834 */ 00835 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp) 00836 { 00837 return lstrcmpA(lpszSrc, lpszCmp); 00838 } 00839 00840 /************************************************************************* 00841 * @ [SHLWAPI.156] 00842 * 00843 * Unicode version of StrCmpCA. 00844 */ 00845 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp) 00846 { 00847 return lstrcmpW(lpszSrc, lpszCmp); 00848 } 00849 00850 /************************************************************************* 00851 * @ [SHLWAPI.157] 00852 * 00853 * Compare two Ascii strings, ignoring case. 00854 * 00855 * PARAMS 00856 * lpszSrc [I] Source string 00857 * lpszCmp [I] String to compare to lpszSrc 00858 * 00859 * RETURNS 00860 * A number greater than, less than or equal to 0 depending on whether 00861 * lpszSrc is greater than, less than or equal to lpszCmp. 00862 */ 00863 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp) 00864 { 00865 return lstrcmpiA(lpszSrc, lpszCmp); 00866 } 00867 00868 /************************************************************************* 00869 * @ [SHLWAPI.158] 00870 * 00871 * Unicode version of StrCmpICA. 00872 */ 00873 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp) 00874 { 00875 return lstrcmpiW(lpszSrc, lpszCmp); 00876 } 00877 00878 /************************************************************************* 00879 * @ [SHLWAPI.160] 00880 * 00881 * Get an identification string for the OS and explorer. 00882 * 00883 * PARAMS 00884 * lpszDest [O] Destination for Id string 00885 * dwDestLen [I] Length of lpszDest 00886 * 00887 * RETURNS 00888 * TRUE, If the string was created successfully 00889 * FALSE, Otherwise 00890 */ 00891 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen) 00892 { 00893 WCHAR buff[2084]; 00894 00895 TRACE("(%p,%d)\n", lpszDest, dwDestLen); 00896 00897 if (lpszDest && SHAboutInfoW(buff, dwDestLen)) 00898 { 00899 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL); 00900 return TRUE; 00901 } 00902 return FALSE; 00903 } 00904 00905 /************************************************************************* 00906 * @ [SHLWAPI.161] 00907 * 00908 * Unicode version of SHAboutInfoA. 00909 */ 00910 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen) 00911 { 00912 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\', 00913 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t', 00914 ' ','E','x','p','l','o','r','e','r','\0' }; 00915 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\', 00916 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ', 00917 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' }; 00918 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\', 00919 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', 00920 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' }; 00921 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\', 00922 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t', 00923 ' ','E','x','p','l','o','r','e','r','\\', 00924 'R','e','g','i','s','t','r','a','t','i','o','n','\0' }; 00925 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' }; 00926 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d', 00927 'V','e','r','s','i','o','n','\0' }; 00928 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d', 00929 'O','w','n','e','r','\0' }; 00930 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d', 00931 'O','r','g','a','n','i','z','a','t','i','o','n','\0' }; 00932 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' }; 00933 static const WCHAR szUpdate[] = { 'I','E','A','K', 00934 'U','p','d','a','t','e','U','r','l','\0' }; 00935 static const WCHAR szHelp[] = { 'I','E','A','K', 00936 'H','e','l','p','S','t','r','i','n','g','\0' }; 00937 WCHAR buff[2084]; 00938 HKEY hReg; 00939 DWORD dwType, dwLen; 00940 00941 TRACE("(%p,%d)\n", lpszDest, dwDestLen); 00942 00943 if (!lpszDest) 00944 return FALSE; 00945 00946 *lpszDest = '\0'; 00947 00948 /* Try the NT key first, followed by 95/98 key */ 00949 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) && 00950 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg)) 00951 return FALSE; 00952 00953 /* OS Version */ 00954 buff[0] = '\0'; 00955 dwLen = 30; 00956 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen)) 00957 { 00958 DWORD dwStrLen = strlenW(buff); 00959 dwLen = 30 - dwStrLen; 00960 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, 00961 szCustomized, &dwType, buff+dwStrLen, &dwLen); 00962 } 00963 StrCatBuffW(lpszDest, buff, dwDestLen); 00964 00965 /* ~Registered Owner */ 00966 buff[0] = '~'; 00967 dwLen = 256; 00968 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen)) 00969 buff[1] = '\0'; 00970 StrCatBuffW(lpszDest, buff, dwDestLen); 00971 00972 /* ~Registered Organization */ 00973 dwLen = 256; 00974 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen)) 00975 buff[1] = '\0'; 00976 StrCatBuffW(lpszDest, buff, dwDestLen); 00977 00978 /* FIXME: Not sure where this number comes from */ 00979 buff[0] = '~'; 00980 buff[1] = '0'; 00981 buff[2] = '\0'; 00982 StrCatBuffW(lpszDest, buff, dwDestLen); 00983 00984 /* ~Product Id */ 00985 dwLen = 256; 00986 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen)) 00987 buff[1] = '\0'; 00988 StrCatBuffW(lpszDest, buff, dwDestLen); 00989 00990 /* ~IE Update Url */ 00991 dwLen = 2048; 00992 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen)) 00993 buff[1] = '\0'; 00994 StrCatBuffW(lpszDest, buff, dwDestLen); 00995 00996 /* ~IE Help String */ 00997 dwLen = 256; 00998 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen)) 00999 buff[1] = '\0'; 01000 StrCatBuffW(lpszDest, buff, dwDestLen); 01001 01002 RegCloseKey(hReg); 01003 return TRUE; 01004 } 01005 01006 /************************************************************************* 01007 * @ [SHLWAPI.163] 01008 * 01009 * Call IOleCommandTarget_QueryStatus() on an object. 01010 * 01011 * PARAMS 01012 * lpUnknown [I] Object supporting the IOleCommandTarget interface 01013 * pguidCmdGroup [I] GUID for the command group 01014 * cCmds [I] 01015 * prgCmds [O] Commands 01016 * pCmdText [O] Command text 01017 * 01018 * RETURNS 01019 * Success: S_OK. 01020 * Failure: E_FAIL, if lpUnknown is NULL. 01021 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget. 01022 * Otherwise, an error code from IOleCommandTarget_QueryStatus(). 01023 */ 01024 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup, 01025 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText) 01026 { 01027 HRESULT hRet = E_FAIL; 01028 01029 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText); 01030 01031 if (lpUnknown) 01032 { 01033 IOleCommandTarget* lpOle; 01034 01035 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget, 01036 (void**)&lpOle); 01037 01038 if (SUCCEEDED(hRet) && lpOle) 01039 { 01040 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds, 01041 prgCmds, pCmdText); 01042 IOleCommandTarget_Release(lpOle); 01043 } 01044 } 01045 return hRet; 01046 } 01047 01048 /************************************************************************* 01049 * @ [SHLWAPI.164] 01050 * 01051 * Call IOleCommandTarget_Exec() on an object. 01052 * 01053 * PARAMS 01054 * lpUnknown [I] Object supporting the IOleCommandTarget interface 01055 * pguidCmdGroup [I] GUID for the command group 01056 * 01057 * RETURNS 01058 * Success: S_OK. 01059 * Failure: E_FAIL, if lpUnknown is NULL. 01060 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget. 01061 * Otherwise, an error code from IOleCommandTarget_Exec(). 01062 */ 01063 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup, 01064 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn, 01065 VARIANT* pvaOut) 01066 { 01067 HRESULT hRet = E_FAIL; 01068 01069 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID, 01070 nCmdexecopt, pvaIn, pvaOut); 01071 01072 if (lpUnknown) 01073 { 01074 IOleCommandTarget* lpOle; 01075 01076 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget, 01077 (void**)&lpOle); 01078 if (SUCCEEDED(hRet) && lpOle) 01079 { 01080 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID, 01081 nCmdexecopt, pvaIn, pvaOut); 01082 IOleCommandTarget_Release(lpOle); 01083 } 01084 } 01085 return hRet; 01086 } 01087 01088 /************************************************************************* 01089 * @ [SHLWAPI.165] 01090 * 01091 * Retrieve, modify, and re-set a value from a window. 01092 * 01093 * PARAMS 01094 * hWnd [I] Window to get value from 01095 * offset [I] Offset of value 01096 * mask [I] Mask for flags 01097 * flags [I] Bits to set in window value 01098 * 01099 * RETURNS 01100 * The new value as it was set, or 0 if any parameter is invalid. 01101 * 01102 * NOTES 01103 * Only bits specified in mask are affected - set if present in flags and 01104 * reset otherwise. 01105 */ 01106 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT mask, UINT flags) 01107 { 01108 LONG ret = GetWindowLongW(hwnd, offset); 01109 LONG new_flags = (flags & mask) | (ret & ~mask); 01110 01111 TRACE("%p %d %x %x\n", hwnd, offset, mask, flags); 01112 01113 if (new_flags != ret) 01114 ret = SetWindowLongW(hwnd, offset, new_flags); 01115 return ret; 01116 } 01117 01118 /************************************************************************* 01119 * @ [SHLWAPI.167] 01120 * 01121 * Change a window's parent. 01122 * 01123 * PARAMS 01124 * hWnd [I] Window to change parent of 01125 * hWndParent [I] New parent window 01126 * 01127 * RETURNS 01128 * The old parent of hWnd. 01129 * 01130 * NOTES 01131 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP. 01132 * If hWndParent is NOT NULL then we set the WS_CHILD style. 01133 */ 01134 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent) 01135 { 01136 TRACE("%p, %p\n", hWnd, hWndParent); 01137 01138 if(GetParent(hWnd) == hWndParent) 01139 return 0; 01140 01141 if(hWndParent) 01142 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD); 01143 else 01144 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP); 01145 01146 return SetParent(hWnd, hWndParent); 01147 } 01148 01149 /************************************************************************* 01150 * @ [SHLWAPI.168] 01151 * 01152 * Locate and advise a connection point in an IConnectionPointContainer object. 01153 * 01154 * PARAMS 01155 * lpUnkSink [I] Sink for the connection point advise call 01156 * riid [I] REFIID of connection point to advise 01157 * fConnect [I] TRUE = Connection being establisted, FALSE = broken 01158 * lpUnknown [I] Object supporting the IConnectionPointContainer interface 01159 * lpCookie [O] Pointer to connection point cookie 01160 * lppCP [O] Destination for the IConnectionPoint found 01161 * 01162 * RETURNS 01163 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint 01164 * that was advised. The caller is responsible for releasing it. 01165 * Failure: E_FAIL, if any arguments are invalid. 01166 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer, 01167 * Or an HRESULT error code if any call fails. 01168 */ 01169 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL fConnect, 01170 IUnknown* lpUnknown, LPDWORD lpCookie, 01171 IConnectionPoint **lppCP) 01172 { 01173 HRESULT hRet; 01174 IConnectionPointContainer* lpContainer; 01175 IConnectionPoint *lpCP; 01176 01177 if(!lpUnknown || (fConnect && !lpUnkSink)) 01178 return E_FAIL; 01179 01180 if(lppCP) 01181 *lppCP = NULL; 01182 01183 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, 01184 (void**)&lpContainer); 01185 if (SUCCEEDED(hRet)) 01186 { 01187 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP); 01188 01189 if (SUCCEEDED(hRet)) 01190 { 01191 if(!fConnect) 01192 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie); 01193 else 01194 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie); 01195 01196 if (FAILED(hRet)) 01197 *lpCookie = 0; 01198 01199 if (lppCP && SUCCEEDED(hRet)) 01200 *lppCP = lpCP; /* Caller keeps the interface */ 01201 else 01202 IConnectionPoint_Release(lpCP); /* Release it */ 01203 } 01204 01205 IUnknown_Release(lpContainer); 01206 } 01207 return hRet; 01208 } 01209 01210 /************************************************************************* 01211 * @ [SHLWAPI.169] 01212 * 01213 * Release an interface and zero a supplied pointer. 01214 * 01215 * PARAMS 01216 * lpUnknown [I] Object to release 01217 * 01218 * RETURNS 01219 * Nothing. 01220 */ 01221 void WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown) 01222 { 01223 TRACE("(%p)\n", lpUnknown); 01224 01225 if(!lpUnknown || !*lpUnknown) return; 01226 01227 TRACE("doing Release\n"); 01228 01229 IUnknown_Release(*lpUnknown); 01230 *lpUnknown = NULL; 01231 } 01232 01233 /************************************************************************* 01234 * @ [SHLWAPI.170] 01235 * 01236 * Skip '//' if present in a string. 01237 * 01238 * PARAMS 01239 * lpszSrc [I] String to check for '//' 01240 * 01241 * RETURNS 01242 * Success: The next character after the '//' or the string if not present 01243 * Failure: NULL, if lpszStr is NULL. 01244 */ 01245 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc) 01246 { 01247 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/') 01248 lpszSrc += 2; 01249 return lpszSrc; 01250 } 01251 01252 /************************************************************************* 01253 * @ [SHLWAPI.171] 01254 * 01255 * Check if two interfaces come from the same object. 01256 * 01257 * PARAMS 01258 * lpInt1 [I] Interface to check against lpInt2. 01259 * lpInt2 [I] Interface to check against lpInt1. 01260 * 01261 * RETURNS 01262 * TRUE, If the interfaces come from the same object. 01263 * FALSE Otherwise. 01264 */ 01265 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2) 01266 { 01267 IUnknown *lpUnknown1, *lpUnknown2; 01268 BOOL ret; 01269 01270 TRACE("(%p %p)\n", lpInt1, lpInt2); 01271 01272 if (!lpInt1 || !lpInt2) 01273 return FALSE; 01274 01275 if (lpInt1 == lpInt2) 01276 return TRUE; 01277 01278 if (IUnknown_QueryInterface(lpInt1, &IID_IUnknown, (void**)&lpUnknown1) != S_OK) 01279 return FALSE; 01280 01281 if (IUnknown_QueryInterface(lpInt2, &IID_IUnknown, (void**)&lpUnknown2) != S_OK) 01282 { 01283 IUnknown_Release(lpUnknown1); 01284 return FALSE; 01285 } 01286 01287 ret = lpUnknown1 == lpUnknown2; 01288 01289 IUnknown_Release(lpUnknown1); 01290 IUnknown_Release(lpUnknown2); 01291 01292 return ret; 01293 } 01294 01295 /************************************************************************* 01296 * @ [SHLWAPI.172] 01297 * 01298 * Get the window handle of an object. 01299 * 01300 * PARAMS 01301 * lpUnknown [I] Object to get the window handle of 01302 * lphWnd [O] Destination for window handle 01303 * 01304 * RETURNS 01305 * Success: S_OK. lphWnd contains the objects window handle. 01306 * Failure: An HRESULT error code. 01307 * 01308 * NOTES 01309 * lpUnknown is expected to support one of the following interfaces: 01310 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView(). 01311 */ 01312 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd) 01313 { 01314 IUnknown *lpOle; 01315 HRESULT hRet = E_FAIL; 01316 01317 TRACE("(%p,%p)\n", lpUnknown, lphWnd); 01318 01319 if (!lpUnknown) 01320 return hRet; 01321 01322 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle); 01323 01324 if (FAILED(hRet)) 01325 { 01326 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle); 01327 01328 if (FAILED(hRet)) 01329 { 01330 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite, 01331 (void**)&lpOle); 01332 } 01333 } 01334 01335 if (SUCCEEDED(hRet)) 01336 { 01337 /* Lazyness here - Since GetWindow() is the first method for the above 3 01338 * interfaces, we use the same call for them all. 01339 */ 01340 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd); 01341 IUnknown_Release(lpOle); 01342 if (lphWnd) 01343 TRACE("Returning HWND=%p\n", *lphWnd); 01344 } 01345 01346 return hRet; 01347 } 01348 01349 /************************************************************************* 01350 * @ [SHLWAPI.173] 01351 * 01352 * Call a SetOwner method of IShellService from specified object. 01353 * 01354 * PARAMS 01355 * iface [I] Object that supports IShellService 01356 * pUnk [I] Argument for the SetOwner call 01357 * 01358 * RETURNS 01359 * Corresponding return value from last call or E_FAIL for null input 01360 */ 01361 HRESULT WINAPI IUnknown_SetOwner(IUnknown *iface, IUnknown *pUnk) 01362 { 01363 IShellService *service; 01364 HRESULT hr; 01365 01366 TRACE("(%p, %p)\n", iface, pUnk); 01367 01368 if (!iface) return E_FAIL; 01369 01370 hr = IUnknown_QueryInterface(iface, &IID_IShellService, (void**)&service); 01371 if (hr == S_OK) 01372 { 01373 hr = IShellService_SetOwner(service, pUnk); 01374 IShellService_Release(service); 01375 } 01376 01377 return hr; 01378 } 01379 01380 /************************************************************************* 01381 * @ [SHLWAPI.174] 01382 * 01383 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on 01384 * an object. 01385 * 01386 */ 01387 HRESULT WINAPI IUnknown_SetSite( 01388 IUnknown *obj, /* [in] OLE object */ 01389 IUnknown *site) /* [in] Site interface */ 01390 { 01391 HRESULT hr; 01392 IObjectWithSite *iobjwithsite; 01393 IInternetSecurityManager *isecmgr; 01394 01395 if (!obj) return E_FAIL; 01396 01397 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite); 01398 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite); 01399 if (SUCCEEDED(hr)) 01400 { 01401 hr = IObjectWithSite_SetSite(iobjwithsite, site); 01402 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr); 01403 IUnknown_Release(iobjwithsite); 01404 } 01405 else 01406 { 01407 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr); 01408 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr); 01409 if (FAILED(hr)) return hr; 01410 01411 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site); 01412 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr); 01413 IUnknown_Release(isecmgr); 01414 } 01415 return hr; 01416 } 01417 01418 /************************************************************************* 01419 * @ [SHLWAPI.175] 01420 * 01421 * Call IPersist_GetClassID() on an object. 01422 * 01423 * PARAMS 01424 * lpUnknown [I] Object supporting the IPersist interface 01425 * lpClassId [O] Destination for Class Id 01426 * 01427 * RETURNS 01428 * Success: S_OK. lpClassId contains the Class Id requested. 01429 * Failure: E_FAIL, If lpUnknown is NULL, 01430 * E_NOINTERFACE If lpUnknown does not support IPersist, 01431 * Or an HRESULT error code. 01432 */ 01433 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId) 01434 { 01435 IPersist* lpPersist; 01436 HRESULT hRet = E_FAIL; 01437 01438 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId)); 01439 01440 if (lpUnknown) 01441 { 01442 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist); 01443 if (SUCCEEDED(hRet)) 01444 { 01445 IPersist_GetClassID(lpPersist, lpClassId); 01446 IPersist_Release(lpPersist); 01447 } 01448 } 01449 return hRet; 01450 } 01451 01452 /************************************************************************* 01453 * @ [SHLWAPI.176] 01454 * 01455 * Retrieve a Service Interface from an object. 01456 * 01457 * PARAMS 01458 * lpUnknown [I] Object to get an IServiceProvider interface from 01459 * sid [I] Service ID for IServiceProvider_QueryService() call 01460 * riid [I] Function requested for QueryService call 01461 * lppOut [O] Destination for the service interface pointer 01462 * 01463 * RETURNS 01464 * Success: S_OK. lppOut contains an object providing the requested service 01465 * Failure: An HRESULT error code 01466 * 01467 * NOTES 01468 * lpUnknown is expected to support the IServiceProvider interface. 01469 */ 01470 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid, 01471 LPVOID *lppOut) 01472 { 01473 IServiceProvider* pService = NULL; 01474 HRESULT hRet; 01475 01476 if (!lppOut) 01477 return E_FAIL; 01478 01479 *lppOut = NULL; 01480 01481 if (!lpUnknown) 01482 return E_FAIL; 01483 01484 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider, 01485 (LPVOID*)&pService); 01486 01487 if (hRet == S_OK && pService) 01488 { 01489 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService); 01490 01491 /* Get a Service interface from the object */ 01492 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut); 01493 01494 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut); 01495 01496 IUnknown_Release(pService); 01497 } 01498 return hRet; 01499 } 01500 01501 /************************************************************************* 01502 * @ [SHLWAPI.484] 01503 * 01504 * Calls IOleCommandTarget::Exec() for specified service object. 01505 * 01506 * PARAMS 01507 * lpUnknown [I] Object to get an IServiceProvider interface from 01508 * service [I] Service ID for IServiceProvider_QueryService() call 01509 * group [I] Group ID for IOleCommandTarget::Exec() call 01510 * cmdId [I] Command ID for IOleCommandTarget::Exec() call 01511 * cmdOpt [I] Options flags for command 01512 * pIn [I] Input arguments for command 01513 * pOut [O] Output arguments for command 01514 * 01515 * RETURNS 01516 * Success: S_OK. lppOut contains an object providing the requested service 01517 * Failure: An HRESULT error code 01518 * 01519 * NOTES 01520 * lpUnknown is expected to support the IServiceProvider interface. 01521 */ 01522 HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *lpUnknown, REFIID service, 01523 const GUID *group, DWORD cmdId, DWORD cmdOpt, VARIANT *pIn, VARIANT *pOut) 01524 { 01525 IOleCommandTarget *target; 01526 HRESULT hr; 01527 01528 TRACE("%p %s %s %d %08x %p %p\n", lpUnknown, debugstr_guid(service), 01529 debugstr_guid(group), cmdId, cmdOpt, pIn, pOut); 01530 01531 hr = IUnknown_QueryService(lpUnknown, service, &IID_IOleCommandTarget, (void**)&target); 01532 if (hr == S_OK) 01533 { 01534 hr = IOleCommandTarget_Exec(target, group, cmdId, cmdOpt, pIn, pOut); 01535 IOleCommandTarget_Release(target); 01536 } 01537 01538 TRACE("<-- hr=0x%08x\n", hr); 01539 01540 return hr; 01541 } 01542 01543 /************************************************************************* 01544 * @ [SHLWAPI.514] 01545 * 01546 * Calls IProfferService methods to proffer/revoke specified service. 01547 * 01548 * PARAMS 01549 * lpUnknown [I] Object to get an IServiceProvider interface from 01550 * service [I] Service ID for IProfferService::Proffer/Revoke calls 01551 * pService [I] Service to proffer. If NULL ::Revoke is called 01552 * pCookie [IO] Group ID for IOleCommandTarget::Exec() call 01553 * 01554 * RETURNS 01555 * Success: S_OK. IProffer method returns S_OK 01556 * Failure: An HRESULT error code 01557 * 01558 * NOTES 01559 * lpUnknown is expected to support the IServiceProvider interface. 01560 */ 01561 HRESULT WINAPI IUnknown_ProfferService(IUnknown *lpUnknown, REFGUID service, IServiceProvider *pService, DWORD *pCookie) 01562 { 01563 IProfferService *proffer; 01564 HRESULT hr; 01565 01566 TRACE("%p %s %p %p\n", lpUnknown, debugstr_guid(service), pService, pCookie); 01567 01568 hr = IUnknown_QueryService(lpUnknown, &IID_IProfferService, &IID_IProfferService, (void**)&proffer); 01569 if (hr == S_OK) 01570 { 01571 if (pService) 01572 hr = IProfferService_ProfferService(proffer, service, pService, pCookie); 01573 else 01574 hr = IProfferService_RevokeService(proffer, *pCookie); 01575 01576 IProfferService_Release(proffer); 01577 } 01578 01579 return hr; 01580 } 01581 01582 /************************************************************************* 01583 * @ [SHLWAPI.479] 01584 * 01585 * Call an object's UIActivateIO method. 01586 * 01587 * PARAMS 01588 * unknown [I] Object to call the UIActivateIO method on 01589 * activate [I] Parameter for UIActivateIO call 01590 * msg [I] Parameter for UIActivateIO call 01591 * 01592 * RETURNS 01593 * Success: Value of UI_ActivateIO call 01594 * Failure: An HRESULT error code 01595 * 01596 * NOTES 01597 * unknown is expected to support the IInputObject interface. 01598 */ 01599 HRESULT WINAPI IUnknown_UIActivateIO(IUnknown *unknown, BOOL activate, LPMSG msg) 01600 { 01601 IInputObject* object = NULL; 01602 HRESULT ret; 01603 01604 if (!unknown) 01605 return E_FAIL; 01606 01607 /* Get an IInputObject interface from the object */ 01608 ret = IUnknown_QueryInterface(unknown, &IID_IInputObject, (LPVOID*) &object); 01609 01610 if (ret == S_OK) 01611 { 01612 ret = IInputObject_UIActivateIO(object, activate, msg); 01613 IUnknown_Release(object); 01614 } 01615 01616 return ret; 01617 } 01618 01619 /************************************************************************* 01620 * @ [SHLWAPI.177] 01621 * 01622 * Loads a popup menu. 01623 * 01624 * PARAMS 01625 * hInst [I] Instance handle 01626 * szName [I] Menu name 01627 * 01628 * RETURNS 01629 * Success: TRUE. 01630 * Failure: FALSE. 01631 */ 01632 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName) 01633 { 01634 HMENU hMenu; 01635 01636 TRACE("%p %s\n", hInst, debugstr_w(szName)); 01637 01638 if ((hMenu = LoadMenuW(hInst, szName))) 01639 { 01640 if (GetSubMenu(hMenu, 0)) 01641 RemoveMenu(hMenu, 0, MF_BYPOSITION); 01642 01643 DestroyMenu(hMenu); 01644 return TRUE; 01645 } 01646 return FALSE; 01647 } 01648 01649 typedef struct _enumWndData 01650 { 01651 UINT uiMsgId; 01652 WPARAM wParam; 01653 LPARAM lParam; 01654 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM); 01655 } enumWndData; 01656 01657 /* Callback for SHLWAPI_178 */ 01658 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam) 01659 { 01660 enumWndData *data = (enumWndData *)lParam; 01661 01662 TRACE("(%p,%p)\n", hWnd, data); 01663 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam); 01664 return TRUE; 01665 } 01666 01667 /************************************************************************* 01668 * @ [SHLWAPI.178] 01669 * 01670 * Send or post a message to every child of a window. 01671 * 01672 * PARAMS 01673 * hWnd [I] Window whose children will get the messages 01674 * uiMsgId [I] Message Id 01675 * wParam [I] WPARAM of message 01676 * lParam [I] LPARAM of message 01677 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA() 01678 * 01679 * RETURNS 01680 * Nothing. 01681 * 01682 * NOTES 01683 * The appropriate ASCII or Unicode function is called for the window. 01684 */ 01685 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend) 01686 { 01687 enumWndData data; 01688 01689 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend); 01690 01691 if(hWnd) 01692 { 01693 data.uiMsgId = uiMsgId; 01694 data.wParam = wParam; 01695 data.lParam = lParam; 01696 01697 if (bSend) 01698 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA; 01699 else 01700 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA; 01701 01702 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data); 01703 } 01704 } 01705 01706 /************************************************************************* 01707 * @ [SHLWAPI.180] 01708 * 01709 * Remove all sub-menus from a menu. 01710 * 01711 * PARAMS 01712 * hMenu [I] Menu to remove sub-menus from 01713 * 01714 * RETURNS 01715 * Success: 0. All sub-menus under hMenu are removed 01716 * Failure: -1, if any parameter is invalid 01717 */ 01718 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu) 01719 { 01720 int iItemCount = GetMenuItemCount(hMenu) - 1; 01721 01722 TRACE("%p\n", hMenu); 01723 01724 while (iItemCount >= 0) 01725 { 01726 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount); 01727 if (hSubMenu) 01728 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION); 01729 iItemCount--; 01730 } 01731 return iItemCount; 01732 } 01733 01734 /************************************************************************* 01735 * @ [SHLWAPI.181] 01736 * 01737 * Enable or disable a menu item. 01738 * 01739 * PARAMS 01740 * hMenu [I] Menu holding menu item 01741 * uID [I] ID of menu item to enable/disable 01742 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item. 01743 * 01744 * RETURNS 01745 * The return code from EnableMenuItem. 01746 */ 01747 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable) 01748 { 01749 TRACE("%p, %u, %d\n", hMenu, wItemID, bEnable); 01750 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED); 01751 } 01752 01753 /************************************************************************* 01754 * @ [SHLWAPI.182] 01755 * 01756 * Check or uncheck a menu item. 01757 * 01758 * PARAMS 01759 * hMenu [I] Menu holding menu item 01760 * uID [I] ID of menu item to check/uncheck 01761 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item. 01762 * 01763 * RETURNS 01764 * The return code from CheckMenuItem. 01765 */ 01766 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck) 01767 { 01768 TRACE("%p, %u, %d\n", hMenu, uID, bCheck); 01769 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED); 01770 } 01771 01772 /************************************************************************* 01773 * @ [SHLWAPI.183] 01774 * 01775 * Register a window class if it isn't already. 01776 * 01777 * PARAMS 01778 * lpWndClass [I] Window class to register 01779 * 01780 * RETURNS 01781 * The result of the RegisterClassA call. 01782 */ 01783 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass) 01784 { 01785 WNDCLASSA wca; 01786 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca)) 01787 return TRUE; 01788 return (DWORD)RegisterClassA(wndclass); 01789 } 01790 01791 /************************************************************************* 01792 * @ [SHLWAPI.186] 01793 */ 01794 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, 01795 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect) 01796 { 01797 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY; 01798 POINTL pt = { 0, 0 }; 01799 01800 TRACE("%p %p 0x%08x %p %p\n", pDrop, pDataObj, grfKeyState, lpPt, pdwEffect); 01801 01802 if (!lpPt) 01803 lpPt = &pt; 01804 01805 if (!pdwEffect) 01806 pdwEffect = &dwEffect; 01807 01808 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect); 01809 01810 if (*pdwEffect != DROPEFFECT_NONE) 01811 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect); 01812 01813 IDropTarget_DragLeave(pDrop); 01814 return TRUE; 01815 } 01816 01817 /************************************************************************* 01818 * @ [SHLWAPI.187] 01819 * 01820 * Call IPersistPropertyBag_Load() on an object. 01821 * 01822 * PARAMS 01823 * lpUnknown [I] Object supporting the IPersistPropertyBag interface 01824 * lpPropBag [O] Destination for loaded IPropertyBag 01825 * 01826 * RETURNS 01827 * Success: S_OK. 01828 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL. 01829 */ 01830 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag) 01831 { 01832 IPersistPropertyBag* lpPPBag; 01833 HRESULT hRet = E_FAIL; 01834 01835 TRACE("(%p,%p)\n", lpUnknown, lpPropBag); 01836 01837 if (lpUnknown) 01838 { 01839 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag, 01840 (void**)&lpPPBag); 01841 if (SUCCEEDED(hRet) && lpPPBag) 01842 { 01843 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL); 01844 IPersistPropertyBag_Release(lpPPBag); 01845 } 01846 } 01847 return hRet; 01848 } 01849 01850 /************************************************************************* 01851 * @ [SHLWAPI.188] 01852 * 01853 * Call IOleControlSite_TranslateAccelerator() on an object. 01854 * 01855 * PARAMS 01856 * lpUnknown [I] Object supporting the IOleControlSite interface. 01857 * lpMsg [I] Key message to be processed. 01858 * dwModifiers [I] Flags containing the state of the modifier keys. 01859 * 01860 * RETURNS 01861 * Success: S_OK. 01862 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL. 01863 */ 01864 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers) 01865 { 01866 IOleControlSite* lpCSite = NULL; 01867 HRESULT hRet = E_INVALIDARG; 01868 01869 TRACE("(%p,%p,0x%08x)\n", lpUnknown, lpMsg, dwModifiers); 01870 if (lpUnknown) 01871 { 01872 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite, 01873 (void**)&lpCSite); 01874 if (SUCCEEDED(hRet) && lpCSite) 01875 { 01876 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers); 01877 IOleControlSite_Release(lpCSite); 01878 } 01879 } 01880 return hRet; 01881 } 01882 01883 01884 /************************************************************************* 01885 * @ [SHLWAPI.189] 01886 * 01887 * Call IOleControlSite_OnFocus() on an object. 01888 * 01889 * PARAMS 01890 * lpUnknown [I] Object supporting the IOleControlSite interface. 01891 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE). 01892 * 01893 * RETURNS 01894 * Success: S_OK. 01895 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL. 01896 */ 01897 HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus) 01898 { 01899 IOleControlSite* lpCSite = NULL; 01900 HRESULT hRet = E_FAIL; 01901 01902 TRACE("(%p, %d)\n", lpUnknown, fGotFocus); 01903 if (lpUnknown) 01904 { 01905 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite, 01906 (void**)&lpCSite); 01907 if (SUCCEEDED(hRet) && lpCSite) 01908 { 01909 hRet = IOleControlSite_OnFocus(lpCSite, fGotFocus); 01910 IOleControlSite_Release(lpCSite); 01911 } 01912 } 01913 return hRet; 01914 } 01915 01916 /************************************************************************* 01917 * @ [SHLWAPI.190] 01918 */ 01919 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1, 01920 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4) 01921 { 01922 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */ 01923 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 }; 01924 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */ 01925 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 }; 01926 HRESULT hRet = E_INVALIDARG; 01927 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */ 01928 01929 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4); 01930 01931 if (lpUnknown && lpArg4) 01932 { 01933 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id, 01934 (REFGUID)function_id, (void**)&lpUnkInner); 01935 01936 if (SUCCEEDED(hRet) && lpUnkInner) 01937 { 01938 /* FIXME: The type of service object requested is unknown, however 01939 * testing shows that its first method is called with 4 parameters. 01940 * Fake this by using IParseDisplayName_ParseDisplayName since the 01941 * signature and position in the vtable matches our unknown object type. 01942 */ 01943 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner, 01944 lpArg1, lpArg2, lpArg3, lpArg4); 01945 IUnknown_Release(lpUnkInner); 01946 } 01947 } 01948 return hRet; 01949 } 01950 01951 /************************************************************************* 01952 * @ [SHLWAPI.192] 01953 * 01954 * Get a sub-menu from a menu item. 01955 * 01956 * PARAMS 01957 * hMenu [I] Menu to get sub-menu from 01958 * uID [I] ID of menu item containing sub-menu 01959 * 01960 * RETURNS 01961 * The sub-menu of the item, or a NULL handle if any parameters are invalid. 01962 */ 01963 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID) 01964 { 01965 MENUITEMINFOW mi; 01966 01967 TRACE("(%p,%u)\n", hMenu, uID); 01968 01969 mi.cbSize = sizeof(mi); 01970 mi.fMask = MIIM_SUBMENU; 01971 01972 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi)) 01973 return NULL; 01974 01975 return mi.hSubMenu; 01976 } 01977 01978 /************************************************************************* 01979 * @ [SHLWAPI.193] 01980 * 01981 * Get the color depth of the primary display. 01982 * 01983 * PARAMS 01984 * None. 01985 * 01986 * RETURNS 01987 * The color depth of the primary display. 01988 */ 01989 DWORD WINAPI SHGetCurColorRes(void) 01990 { 01991 HDC hdc; 01992 DWORD ret; 01993 01994 TRACE("()\n"); 01995 01996 hdc = GetDC(0); 01997 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES); 01998 ReleaseDC(0, hdc); 01999 return ret; 02000 } 02001 02002 /************************************************************************* 02003 * @ [SHLWAPI.194] 02004 * 02005 * Wait for a message to arrive, with a timeout. 02006 * 02007 * PARAMS 02008 * hand [I] Handle to query 02009 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout 02010 * 02011 * RETURNS 02012 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes. 02013 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a 02014 * message is available. 02015 */ 02016 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout) 02017 { 02018 DWORD dwEndTicks = GetTickCount() + dwTimeout; 02019 DWORD dwRet; 02020 02021 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1) 02022 { 02023 MSG msg; 02024 02025 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE); 02026 02027 if (dwTimeout != INFINITE) 02028 { 02029 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0) 02030 return WAIT_TIMEOUT; 02031 } 02032 } 02033 02034 return dwRet; 02035 } 02036 02037 /************************************************************************* 02038 * @ [SHLWAPI.195] 02039 * 02040 * Determine if a shell folder can be expanded. 02041 * 02042 * PARAMS 02043 * lpFolder [I] Parent folder containing the object to test. 02044 * pidl [I] Id of the object to test. 02045 * 02046 * RETURNS 02047 * Success: S_OK, if the object is expandable, S_FALSE otherwise. 02048 * Failure: E_INVALIDARG, if any argument is invalid. 02049 * 02050 * NOTES 02051 * If the object to be tested does not expose the IQueryInfo() interface it 02052 * will not be identified as an expandable folder. 02053 */ 02054 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl) 02055 { 02056 HRESULT hRet = E_INVALIDARG; 02057 IQueryInfo *lpInfo; 02058 02059 if (lpFolder && pidl) 02060 { 02061 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo, 02062 NULL, (void**)&lpInfo); 02063 if (FAILED(hRet)) 02064 hRet = S_FALSE; /* Doesn't expose IQueryInfo */ 02065 else 02066 { 02067 DWORD dwFlags = 0; 02068 02069 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not 02070 * currently used". Really? You wouldn't be holding out on me would you? 02071 */ 02072 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags); 02073 02074 if (SUCCEEDED(hRet)) 02075 { 02076 /* 0x2 is an undocumented flag apparently indicating expandability */ 02077 hRet = dwFlags & 0x2 ? S_OK : S_FALSE; 02078 } 02079 02080 IQueryInfo_Release(lpInfo); 02081 } 02082 } 02083 return hRet; 02084 } 02085 02086 /************************************************************************* 02087 * @ [SHLWAPI.197] 02088 * 02089 * Blank out a region of text by drawing the background only. 02090 * 02091 * PARAMS 02092 * hDC [I] Device context to draw in 02093 * pRect [I] Area to draw in 02094 * cRef [I] Color to draw in 02095 * 02096 * RETURNS 02097 * Nothing. 02098 */ 02099 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef) 02100 { 02101 COLORREF cOldColor = SetBkColor(hDC, cRef); 02102 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0); 02103 SetBkColor(hDC, cOldColor); 02104 return 0; 02105 } 02106 02107 /************************************************************************* 02108 * @ [SHLWAPI.198] 02109 * 02110 * Return the value associated with a key in a map. 02111 * 02112 * PARAMS 02113 * lpKeys [I] A list of keys of length iLen 02114 * lpValues [I] A list of values associated with lpKeys, of length iLen 02115 * iLen [I] Length of both lpKeys and lpValues 02116 * iKey [I] The key value to look up in lpKeys 02117 * 02118 * RETURNS 02119 * The value in lpValues associated with iKey, or -1 if iKey is not 02120 * found in lpKeys. 02121 * 02122 * NOTES 02123 * - If two elements in the map share the same key, this function returns 02124 * the value closest to the start of the map 02125 * - The native version of this function crashes if lpKeys or lpValues is NULL. 02126 */ 02127 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey) 02128 { 02129 if (lpKeys && lpValues) 02130 { 02131 int i = 0; 02132 02133 while (i < iLen) 02134 { 02135 if (lpKeys[i] == iKey) 02136 return lpValues[i]; /* Found */ 02137 i++; 02138 } 02139 } 02140 return -1; /* Not found */ 02141 } 02142 02143 02144 /************************************************************************* 02145 * @ [SHLWAPI.199] 02146 * 02147 * Copy an interface pointer 02148 * 02149 * PARAMS 02150 * lppDest [O] Destination for copy 02151 * lpUnknown [I] Source for copy 02152 * 02153 * RETURNS 02154 * Nothing. 02155 */ 02156 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown) 02157 { 02158 TRACE("(%p,%p)\n", lppDest, lpUnknown); 02159 02160 IUnknown_AtomicRelease(lppDest); 02161 02162 if (lpUnknown) 02163 { 02164 IUnknown_AddRef(lpUnknown); 02165 *lppDest = lpUnknown; 02166 } 02167 } 02168 02169 /************************************************************************* 02170 * @ [SHLWAPI.200] 02171 * 02172 */ 02173 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved, 02174 REFGUID riidCmdGrp, ULONG cCmds, 02175 OLECMD *prgCmds, OLECMDTEXT* pCmdText) 02176 { 02177 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n", 02178 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText); 02179 02180 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */ 02181 return DRAGDROP_E_NOTREGISTERED; 02182 } 02183 02184 /************************************************************************* 02185 * @ [SHLWAPI.201] 02186 * 02187 */ 02188 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup, 02189 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn, 02190 VARIANT* pvaOut) 02191 { 02192 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup, 02193 nCmdID, nCmdexecopt, pvaIn, pvaOut); 02194 return DRAGDROP_E_NOTREGISTERED; 02195 } 02196 02197 /************************************************************************* 02198 * @ [SHLWAPI.202] 02199 * 02200 */ 02201 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds) 02202 { 02203 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds); 02204 return DRAGDROP_E_NOTREGISTERED; 02205 } 02206 02207 /************************************************************************* 02208 * @ [SHLWAPI.204] 02209 * 02210 * Determine if a window is not a child of another window. 02211 * 02212 * PARAMS 02213 * hParent [I] Suspected parent window 02214 * hChild [I] Suspected child window 02215 * 02216 * RETURNS 02217 * TRUE: If hChild is a child window of hParent 02218 * FALSE: If hChild is not a child window of hParent, or they are equal 02219 */ 02220 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild) 02221 { 02222 TRACE("(%p,%p)\n", hParent, hChild); 02223 02224 if (!hParent || !hChild) 02225 return TRUE; 02226 else if(hParent == hChild) 02227 return FALSE; 02228 return !IsChild(hParent, hChild); 02229 } 02230 02231 /************************************************************************* 02232 * FDSA functions. Manage a dynamic array of fixed size memory blocks. 02233 */ 02234 02235 typedef struct 02236 { 02237 DWORD num_items; /* Number of elements inserted */ 02238 void *mem; /* Ptr to array */ 02239 DWORD blocks_alloced; /* Number of elements allocated */ 02240 BYTE inc; /* Number of elements to grow by when we need to expand */ 02241 BYTE block_size; /* Size in bytes of an element */ 02242 BYTE flags; /* Flags */ 02243 } FDSA_info; 02244 02245 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */ 02246 02247 /************************************************************************* 02248 * @ [SHLWAPI.208] 02249 * 02250 * Initialize an FDSA array. 02251 */ 02252 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem, 02253 DWORD init_blocks) 02254 { 02255 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size, inc, info, mem, init_blocks); 02256 02257 if(inc == 0) 02258 inc = 1; 02259 02260 if(mem) 02261 memset(mem, 0, block_size * init_blocks); 02262 02263 info->num_items = 0; 02264 info->inc = inc; 02265 info->mem = mem; 02266 info->blocks_alloced = init_blocks; 02267 info->block_size = block_size; 02268 info->flags = 0; 02269 02270 return TRUE; 02271 } 02272 02273 /************************************************************************* 02274 * @ [SHLWAPI.209] 02275 * 02276 * Destroy an FDSA array 02277 */ 02278 BOOL WINAPI FDSA_Destroy(FDSA_info *info) 02279 { 02280 TRACE("(%p)\n", info); 02281 02282 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC) 02283 { 02284 HeapFree(GetProcessHeap(), 0, info->mem); 02285 return FALSE; 02286 } 02287 02288 return TRUE; 02289 } 02290 02291 /************************************************************************* 02292 * @ [SHLWAPI.210] 02293 * 02294 * Insert element into an FDSA array 02295 */ 02296 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, const void *block) 02297 { 02298 TRACE("(%p 0x%08x %p)\n", info, where, block); 02299 if(where > info->num_items) 02300 where = info->num_items; 02301 02302 if(info->num_items >= info->blocks_alloced) 02303 { 02304 DWORD size = (info->blocks_alloced + info->inc) * info->block_size; 02305 if(info->flags & 0x1) 02306 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size); 02307 else 02308 { 02309 void *old_mem = info->mem; 02310 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 02311 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size); 02312 } 02313 info->blocks_alloced += info->inc; 02314 info->flags |= 0x1; 02315 } 02316 02317 if(where < info->num_items) 02318 { 02319 memmove((char*)info->mem + (where + 1) * info->block_size, 02320 (char*)info->mem + where * info->block_size, 02321 (info->num_items - where) * info->block_size); 02322 } 02323 memcpy((char*)info->mem + where * info->block_size, block, info->block_size); 02324 02325 info->num_items++; 02326 return where; 02327 } 02328 02329 /************************************************************************* 02330 * @ [SHLWAPI.211] 02331 * 02332 * Delete an element from an FDSA array. 02333 */ 02334 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where) 02335 { 02336 TRACE("(%p 0x%08x)\n", info, where); 02337 02338 if(where >= info->num_items) 02339 return FALSE; 02340 02341 if(where < info->num_items - 1) 02342 { 02343 memmove((char*)info->mem + where * info->block_size, 02344 (char*)info->mem + (where + 1) * info->block_size, 02345 (info->num_items - where - 1) * info->block_size); 02346 } 02347 memset((char*)info->mem + (info->num_items - 1) * info->block_size, 02348 0, info->block_size); 02349 info->num_items--; 02350 return TRUE; 02351 } 02352 02353 /************************************************************************* 02354 * @ [SHLWAPI.219] 02355 * 02356 * Call IUnknown_QueryInterface() on a table of objects. 02357 * 02358 * RETURNS 02359 * Success: S_OK. 02360 * Failure: E_POINTER or E_NOINTERFACE. 02361 */ 02362 HRESULT WINAPI QISearch( 02363 void *base, /* [in] Table of interfaces */ 02364 const QITAB *table, /* [in] Array of REFIIDs and indexes into the table */ 02365 REFIID riid, /* [in] REFIID to get interface for */ 02366 void **ppv) /* [out] Destination for interface pointer */ 02367 { 02368 HRESULT ret; 02369 IUnknown *a_vtbl; 02370 const QITAB *xmove; 02371 02372 TRACE("(%p %p %s %p)\n", base, table, debugstr_guid(riid), ppv); 02373 if (ppv) { 02374 xmove = table; 02375 while (xmove->piid) { 02376 TRACE("trying (offset %d) %s\n", xmove->dwOffset, debugstr_guid(xmove->piid)); 02377 if (IsEqualIID(riid, xmove->piid)) { 02378 a_vtbl = (IUnknown*)(xmove->dwOffset + (LPBYTE)base); 02379 TRACE("matched, returning (%p)\n", a_vtbl); 02380 *ppv = a_vtbl; 02381 IUnknown_AddRef(a_vtbl); 02382 return S_OK; 02383 } 02384 xmove++; 02385 } 02386 02387 if (IsEqualIID(riid, &IID_IUnknown)) { 02388 a_vtbl = (IUnknown*)(table->dwOffset + (LPBYTE)base); 02389 TRACE("returning first for IUnknown (%p)\n", a_vtbl); 02390 *ppv = a_vtbl; 02391 IUnknown_AddRef(a_vtbl); 02392 return S_OK; 02393 } 02394 *ppv = 0; 02395 ret = E_NOINTERFACE; 02396 } else 02397 ret = E_POINTER; 02398 02399 TRACE("-- 0x%08x\n", ret); 02400 return ret; 02401 } 02402 02403 /************************************************************************* 02404 * @ [SHLWAPI.220] 02405 * 02406 * Set the Font for a window and the "PropDlgFont" property of the parent window. 02407 * 02408 * PARAMS 02409 * hWnd [I] Parent Window to set the property 02410 * id [I] Index of child Window to set the Font 02411 * 02412 * RETURNS 02413 * Success: S_OK 02414 * 02415 */ 02416 HRESULT WINAPI SHSetDefaultDialogFont(HWND hWnd, INT id) 02417 { 02418 FIXME("(%p, %d) stub\n", hWnd, id); 02419 return S_OK; 02420 } 02421 02422 /************************************************************************* 02423 * @ [SHLWAPI.221] 02424 * 02425 * Remove the "PropDlgFont" property from a window. 02426 * 02427 * PARAMS 02428 * hWnd [I] Window to remove the property from 02429 * 02430 * RETURNS 02431 * A handle to the removed property, or NULL if it did not exist. 02432 */ 02433 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd) 02434 { 02435 HANDLE hProp; 02436 02437 TRACE("(%p)\n", hWnd); 02438 02439 hProp = GetPropA(hWnd, "PropDlgFont"); 02440 02441 if(hProp) 02442 { 02443 DeleteObject(hProp); 02444 hProp = RemovePropA(hWnd, "PropDlgFont"); 02445 } 02446 return hProp; 02447 } 02448 02449 /************************************************************************* 02450 * @ [SHLWAPI.236] 02451 * 02452 * Load the in-process server of a given GUID. 02453 * 02454 * PARAMS 02455 * refiid [I] GUID of the server to load. 02456 * 02457 * RETURNS 02458 * Success: A handle to the loaded server dll. 02459 * Failure: A NULL handle. 02460 */ 02461 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid) 02462 { 02463 HKEY newkey; 02464 DWORD type, count; 02465 CHAR value[MAX_PATH], string[MAX_PATH]; 02466 02467 strcpy(string, "CLSID\\"); 02468 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6); 02469 strcat(string, "\\InProcServer32"); 02470 02471 count = MAX_PATH; 02472 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey); 02473 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count); 02474 RegCloseKey(newkey); 02475 return LoadLibraryExA(value, 0, 0); 02476 } 02477 02478 /************************************************************************* 02479 * @ [SHLWAPI.237] 02480 * 02481 * Unicode version of SHLWAPI_183. 02482 */ 02483 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass) 02484 { 02485 WNDCLASSW WndClass; 02486 02487 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName)); 02488 02489 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass)) 02490 return TRUE; 02491 return RegisterClassW(lpWndClass); 02492 } 02493 02494 /************************************************************************* 02495 * @ [SHLWAPI.238] 02496 * 02497 * Unregister a list of classes. 02498 * 02499 * PARAMS 02500 * hInst [I] Application instance that registered the classes 02501 * lppClasses [I] List of class names 02502 * iCount [I] Number of names in lppClasses 02503 * 02504 * RETURNS 02505 * Nothing. 02506 */ 02507 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount) 02508 { 02509 WNDCLASSA WndClass; 02510 02511 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount); 02512 02513 while (iCount > 0) 02514 { 02515 if (GetClassInfoA(hInst, *lppClasses, &WndClass)) 02516 UnregisterClassA(*lppClasses, hInst); 02517 lppClasses++; 02518 iCount--; 02519 } 02520 } 02521 02522 /************************************************************************* 02523 * @ [SHLWAPI.239] 02524 * 02525 * Unicode version of SHUnregisterClassesA. 02526 */ 02527 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount) 02528 { 02529 WNDCLASSW WndClass; 02530 02531 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount); 02532 02533 while (iCount > 0) 02534 { 02535 if (GetClassInfoW(hInst, *lppClasses, &WndClass)) 02536 UnregisterClassW(*lppClasses, hInst); 02537 lppClasses++; 02538 iCount--; 02539 } 02540 } 02541 02542 /************************************************************************* 02543 * @ [SHLWAPI.240] 02544 * 02545 * Call The correct (Ascii/Unicode) default window procedure for a window. 02546 * 02547 * PARAMS 02548 * hWnd [I] Window to call the default procedure for 02549 * uMessage [I] Message ID 02550 * wParam [I] WPARAM of message 02551 * lParam [I] LPARAM of message 02552 * 02553 * RETURNS 02554 * The result of calling DefWindowProcA() or DefWindowProcW(). 02555 */ 02556 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) 02557 { 02558 if (IsWindowUnicode(hWnd)) 02559 return DefWindowProcW(hWnd, uMessage, wParam, lParam); 02560 return DefWindowProcA(hWnd, uMessage, wParam, lParam); 02561 } 02562 02563 /************************************************************************* 02564 * @ [SHLWAPI.256] 02565 */ 02566 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite) 02567 { 02568 HRESULT hRet = E_INVALIDARG; 02569 LPOBJECTWITHSITE lpSite = NULL; 02570 02571 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite); 02572 02573 if (lpUnknown && iid && lppSite) 02574 { 02575 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite, 02576 (void**)&lpSite); 02577 if (SUCCEEDED(hRet) && lpSite) 02578 { 02579 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite); 02580 IObjectWithSite_Release(lpSite); 02581 } 02582 } 02583 return hRet; 02584 } 02585 02586 /************************************************************************* 02587 * @ [SHLWAPI.257] 02588 * 02589 * Create a worker window using CreateWindowExA(). 02590 * 02591 * PARAMS 02592 * wndProc [I] Window procedure 02593 * hWndParent [I] Parent window 02594 * dwExStyle [I] Extra style flags 02595 * dwStyle [I] Style flags 02596 * hMenu [I] Window menu 02597 * wnd_extra [I] Window extra bytes value 02598 * 02599 * RETURNS 02600 * Success: The window handle of the newly created window. 02601 * Failure: 0. 02602 */ 02603 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle, 02604 DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra) 02605 { 02606 static const char szClass[] = "WorkerA"; 02607 WNDCLASSA wc; 02608 HWND hWnd; 02609 02610 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n", 02611 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); 02612 02613 /* Create Window class */ 02614 wc.style = 0; 02615 wc.lpfnWndProc = DefWindowProcA; 02616 wc.cbClsExtra = 0; 02617 wc.cbWndExtra = sizeof(LONG_PTR); 02618 wc.hInstance = shlwapi_hInstance; 02619 wc.hIcon = NULL; 02620 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW); 02621 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 02622 wc.lpszMenuName = NULL; 02623 wc.lpszClassName = szClass; 02624 02625 SHRegisterClassA(&wc); 02626 02627 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0, 02628 hWndParent, hMenu, shlwapi_hInstance, 0); 02629 if (hWnd) 02630 { 02631 SetWindowLongPtrW(hWnd, 0, wnd_extra); 02632 02633 if (wndProc) SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc); 02634 } 02635 02636 return hWnd; 02637 } 02638 02639 typedef struct tagPOLICYDATA 02640 { 02641 DWORD policy; /* flags value passed to SHRestricted */ 02642 LPCWSTR appstr; /* application str such as "Explorer" */ 02643 LPCWSTR keystr; /* name of the actual registry key / policy */ 02644 } POLICYDATA, *LPPOLICYDATA; 02645 02646 #define SHELL_NO_POLICY 0xffffffff 02647 02648 /* default shell policy registry key */ 02649 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o', 02650 's','o','f','t','\\','W','i','n','d','o','w','s','\\', 02651 'C','u','r','r','e','n','t','V','e','r','s','i','o','n', 02652 '\\','P','o','l','i','c','i','e','s',0}; 02653 02654 /************************************************************************* 02655 * @ [SHLWAPI.271] 02656 * 02657 * Retrieve a policy value from the registry. 02658 * 02659 * PARAMS 02660 * lpSubKey [I] registry key name 02661 * lpSubName [I] subname of registry key 02662 * lpValue [I] value name of registry value 02663 * 02664 * RETURNS 02665 * the value associated with the registry key or 0 if not found 02666 */ 02667 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue) 02668 { 02669 DWORD retval, datsize = sizeof(retval); 02670 HKEY hKey; 02671 02672 if (!lpSubKey) 02673 lpSubKey = strRegistryPolicyW; 02674 02675 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey); 02676 if (retval != ERROR_SUCCESS) 02677 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey); 02678 if (retval != ERROR_SUCCESS) 02679 return 0; 02680 02681 SHGetValueW(hKey, lpSubName, lpValue, NULL, &retval, &datsize); 02682 RegCloseKey(hKey); 02683 return retval; 02684 } 02685 02686 /************************************************************************* 02687 * @ [SHLWAPI.266] 02688 * 02689 * Helper function to retrieve the possibly cached value for a specific policy 02690 * 02691 * PARAMS 02692 * policy [I] The policy to look for 02693 * initial [I] Main registry key to open, if NULL use default 02694 * polTable [I] Table of known policies, 0 terminated 02695 * polArr [I] Cache array of policy values 02696 * 02697 * RETURNS 02698 * The retrieved policy value or 0 if not successful 02699 * 02700 * NOTES 02701 * This function is used by the native SHRestricted function to search for the 02702 * policy and cache it once retrieved. The current Wine implementation uses a 02703 * different POLICYDATA structure and implements a similar algorithm adapted to 02704 * that structure. 02705 */ 02706 DWORD WINAPI SHRestrictionLookup( 02707 DWORD policy, 02708 LPCWSTR initial, 02709 LPPOLICYDATA polTable, 02710 LPDWORD polArr) 02711 { 02712 TRACE("(0x%08x %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr); 02713 02714 if (!polTable || !polArr) 02715 return 0; 02716 02717 for (;polTable->policy; polTable++, polArr++) 02718 { 02719 if (policy == polTable->policy) 02720 { 02721 /* we have a known policy */ 02722 02723 /* check if this policy has been cached */ 02724 if (*polArr == SHELL_NO_POLICY) 02725 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr); 02726 return *polArr; 02727 } 02728 } 02729 /* we don't know this policy, return 0 */ 02730 TRACE("unknown policy: (%08x)\n", policy); 02731 return 0; 02732 } 02733 02734 /************************************************************************* 02735 * @ [SHLWAPI.267] 02736 * 02737 * Get an interface from an object. 02738 * 02739 * RETURNS 02740 * Success: S_OK. ppv contains the requested interface. 02741 * Failure: An HRESULT error code. 02742 * 02743 * NOTES 02744 * This QueryInterface asks the inner object for an interface. In case 02745 * of aggregation this request would be forwarded by the inner to the 02746 * outer object. This function asks the inner object directly for the 02747 * interface circumventing the forwarding to the outer object. 02748 */ 02749 HRESULT WINAPI SHWeakQueryInterface( 02750 IUnknown * pUnk, /* [in] Outer object */ 02751 IUnknown * pInner, /* [in] Inner object */ 02752 IID * riid, /* [in] Interface GUID to query for */ 02753 LPVOID* ppv) /* [out] Destination for queried interface */ 02754 { 02755 HRESULT hret = E_NOINTERFACE; 02756 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv); 02757 02758 *ppv = NULL; 02759 if(pUnk && pInner) { 02760 hret = IUnknown_QueryInterface(pInner, riid, ppv); 02761 if (SUCCEEDED(hret)) IUnknown_Release(pUnk); 02762 } 02763 TRACE("-- 0x%08x\n", hret); 02764 return hret; 02765 } 02766 02767 /************************************************************************* 02768 * @ [SHLWAPI.268] 02769 * 02770 * Move a reference from one interface to another. 02771 * 02772 * PARAMS 02773 * lpDest [O] Destination to receive the reference 02774 * lppUnknown [O] Source to give up the reference to lpDest 02775 * 02776 * RETURNS 02777 * Nothing. 02778 */ 02779 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown) 02780 { 02781 TRACE("(%p,%p)\n", lpDest, lppUnknown); 02782 02783 if (*lppUnknown) 02784 { 02785 /* Copy Reference*/ 02786 IUnknown_AddRef(lpDest); 02787 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */ 02788 } 02789 } 02790 02791 /************************************************************************* 02792 * @ [SHLWAPI.269] 02793 * 02794 * Convert an ASCII string of a CLSID into a CLSID. 02795 * 02796 * PARAMS 02797 * idstr [I] String representing a CLSID in registry format 02798 * id [O] Destination for the converted CLSID 02799 * 02800 * RETURNS 02801 * Success: TRUE. id contains the converted CLSID. 02802 * Failure: FALSE. 02803 */ 02804 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id) 02805 { 02806 WCHAR wClsid[40]; 02807 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR)); 02808 return SUCCEEDED(CLSIDFromString(wClsid, id)); 02809 } 02810 02811 /************************************************************************* 02812 * @ [SHLWAPI.270] 02813 * 02814 * Unicode version of GUIDFromStringA. 02815 */ 02816 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id) 02817 { 02818 return SUCCEEDED(CLSIDFromString((LPCOLESTR)idstr, id)); 02819 } 02820 02821 /************************************************************************* 02822 * @ [SHLWAPI.276] 02823 * 02824 * Determine if the browser is integrated into the shell, and set a registry 02825 * key accordingly. 02826 * 02827 * PARAMS 02828 * None. 02829 * 02830 * RETURNS 02831 * 1, If the browser is not integrated. 02832 * 2, If the browser is integrated. 02833 * 02834 * NOTES 02835 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is 02836 * either set to TRUE, or removed depending on whether the browser is deemed 02837 * to be integrated. 02838 */ 02839 DWORD WINAPI WhichPlatform(void) 02840 { 02841 static const char szIntegratedBrowser[] = "IntegratedBrowser"; 02842 static DWORD dwState = 0; 02843 HKEY hKey; 02844 DWORD dwRet, dwData, dwSize; 02845 HMODULE hshell32; 02846 02847 if (dwState) 02848 return dwState; 02849 02850 /* If shell32 exports DllGetVersion(), the browser is integrated */ 02851 dwState = 1; 02852 hshell32 = LoadLibraryA("shell32.dll"); 02853 if (hshell32) 02854 { 02855 FARPROC pDllGetVersion; 02856 pDllGetVersion = GetProcAddress(hshell32, "DllGetVersion"); 02857 dwState = pDllGetVersion ? 2 : 1; 02858 FreeLibrary(hshell32); 02859 } 02860 02861 /* Set or delete the key accordingly */ 02862 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, 02863 "Software\\Microsoft\\Internet Explorer", 0, 02864 KEY_ALL_ACCESS, &hKey); 02865 if (!dwRet) 02866 { 02867 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0, 02868 (LPBYTE)&dwData, &dwSize); 02869 02870 if (!dwRet && dwState == 1) 02871 { 02872 /* Value exists but browser is not integrated */ 02873 RegDeleteValueA(hKey, szIntegratedBrowser); 02874 } 02875 else if (dwRet && dwState == 2) 02876 { 02877 /* Browser is integrated but value does not exist */ 02878 dwData = TRUE; 02879 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD, 02880 (LPBYTE)&dwData, sizeof(dwData)); 02881 } 02882 RegCloseKey(hKey); 02883 } 02884 return dwState; 02885 } 02886 02887 /************************************************************************* 02888 * @ [SHLWAPI.278] 02889 * 02890 * Unicode version of SHCreateWorkerWindowA. 02891 */ 02892 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle, 02893 DWORD dwStyle, HMENU hMenu, LONG msg_result) 02894 { 02895 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 }; 02896 WNDCLASSW wc; 02897 HWND hWnd; 02898 02899 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n", 02900 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result); 02901 02902 /* If our OS is natively ANSI, use the ANSI version */ 02903 if (GetVersion() & 0x80000000) /* not NT */ 02904 { 02905 TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion()); 02906 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result); 02907 } 02908 02909 /* Create Window class */ 02910 wc.style = 0; 02911 wc.lpfnWndProc = DefWindowProcW; 02912 wc.cbClsExtra = 0; 02913 wc.cbWndExtra = 4; 02914 wc.hInstance = shlwapi_hInstance; 02915 wc.hIcon = NULL; 02916 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW); 02917 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 02918 wc.lpszMenuName = NULL; 02919 wc.lpszClassName = szClass; 02920 02921 SHRegisterClassW(&wc); 02922 02923 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0, 02924 hWndParent, hMenu, shlwapi_hInstance, 0); 02925 if (hWnd) 02926 { 02927 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, msg_result); 02928 02929 if (wndProc) SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc); 02930 } 02931 02932 return hWnd; 02933 } 02934 02935 /************************************************************************* 02936 * @ [SHLWAPI.279] 02937 * 02938 * Get and show a context menu from a shell folder. 02939 * 02940 * PARAMS 02941 * hWnd [I] Window displaying the shell folder 02942 * lpFolder [I] IShellFolder interface 02943 * lpApidl [I] Id for the particular folder desired 02944 * 02945 * RETURNS 02946 * Success: S_OK. 02947 * Failure: An HRESULT error code indicating the error. 02948 */ 02949 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl) 02950 { 02951 TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl); 02952 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE); 02953 } 02954 02955 /************************************************************************* 02956 * @ [SHLWAPI.281] 02957 * 02958 * _SHPackDispParamsV 02959 */ 02960 HRESULT WINAPI SHPackDispParamsV(DISPPARAMS *params, VARIANTARG *args, UINT cnt, __ms_va_list valist) 02961 { 02962 VARIANTARG *iter; 02963 02964 TRACE("(%p %p %u ...)\n", params, args, cnt); 02965 02966 params->rgvarg = args; 02967 params->rgdispidNamedArgs = NULL; 02968 params->cArgs = cnt; 02969 params->cNamedArgs = 0; 02970 02971 iter = args+cnt; 02972 02973 while(iter-- > args) { 02974 V_VT(iter) = va_arg(valist, enum VARENUM); 02975 02976 TRACE("vt=%d\n", V_VT(iter)); 02977 02978 if(V_VT(iter) & VT_BYREF) { 02979 V_BYREF(iter) = va_arg(valist, LPVOID); 02980 } else { 02981 switch(V_VT(iter)) { 02982 case VT_I4: 02983 V_I4(iter) = va_arg(valist, LONG); 02984 break; 02985 case VT_BSTR: 02986 V_BSTR(iter) = va_arg(valist, BSTR); 02987 break; 02988 case VT_DISPATCH: 02989 V_DISPATCH(iter) = va_arg(valist, IDispatch*); 02990 break; 02991 case VT_BOOL: 02992 V_BOOL(iter) = va_arg(valist, int); 02993 break; 02994 case VT_UNKNOWN: 02995 V_UNKNOWN(iter) = va_arg(valist, IUnknown*); 02996 break; 02997 default: 02998 V_VT(iter) = VT_I4; 02999 V_I4(iter) = va_arg(valist, LONG); 03000 } 03001 } 03002 } 03003 03004 return S_OK; 03005 } 03006 03007 /************************************************************************* 03008 * @ [SHLWAPI.282] 03009 * 03010 * SHPackDispParams 03011 */ 03012 HRESULT WINAPIV SHPackDispParams(DISPPARAMS *params, VARIANTARG *args, UINT cnt, ...) 03013 { 03014 __ms_va_list valist; 03015 HRESULT hres; 03016 03017 __ms_va_start(valist, cnt); 03018 hres = SHPackDispParamsV(params, args, cnt, valist); 03019 __ms_va_end(valist); 03020 return hres; 03021 } 03022 03023 /************************************************************************* 03024 * SHLWAPI_InvokeByIID 03025 * 03026 * This helper function calls IDispatch::Invoke for each sink 03027 * which implements given iid or IDispatch. 03028 * 03029 */ 03030 static HRESULT SHLWAPI_InvokeByIID( 03031 IConnectionPoint* iCP, 03032 REFIID iid, 03033 DISPID dispId, 03034 DISPPARAMS* dispParams) 03035 { 03036 IEnumConnections *enumerator; 03037 CONNECTDATA rgcd; 03038 static DISPPARAMS empty = {NULL, NULL, 0, 0}; 03039 DISPPARAMS* params = dispParams; 03040 03041 HRESULT result = IConnectionPoint_EnumConnections(iCP, &enumerator); 03042 if (FAILED(result)) 03043 return result; 03044 03045 /* Invoke is never happening with an NULL dispParams */ 03046 if (!params) 03047 params = ∅ 03048 03049 while(IEnumConnections_Next(enumerator, 1, &rgcd, NULL)==S_OK) 03050 { 03051 IDispatch *dispIface; 03052 if ((iid && SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, iid, (LPVOID*)&dispIface))) || 03053 SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, &IID_IDispatch, (LPVOID*)&dispIface))) 03054 { 03055 IDispatch_Invoke(dispIface, dispId, &IID_NULL, 0, DISPATCH_METHOD, params, NULL, NULL, NULL); 03056 IDispatch_Release(dispIface); 03057 } 03058 IUnknown_Release(rgcd.pUnk); 03059 } 03060 03061 IEnumConnections_Release(enumerator); 03062 03063 return S_OK; 03064 } 03065 03066 /************************************************************************* 03067 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283] 03068 */ 03069 HRESULT WINAPI IConnectionPoint_InvokeWithCancel( IConnectionPoint* iCP, 03070 DISPID dispId, DISPPARAMS* dispParams, 03071 DWORD unknown1, DWORD unknown2 ) 03072 { 03073 IID iid; 03074 HRESULT result; 03075 03076 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP, dispId, dispParams, unknown1, unknown2); 03077 03078 result = IConnectionPoint_GetConnectionInterface(iCP, &iid); 03079 if (SUCCEEDED(result)) 03080 result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); 03081 else 03082 result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams); 03083 03084 return result; 03085 } 03086 03087 03088 /************************************************************************* 03089 * @ [SHLWAPI.284] 03090 * 03091 * IConnectionPoint_SimpleInvoke 03092 */ 03093 HRESULT WINAPI IConnectionPoint_SimpleInvoke( 03094 IConnectionPoint* iCP, 03095 DISPID dispId, 03096 DISPPARAMS* dispParams) 03097 { 03098 IID iid; 03099 HRESULT result; 03100 03101 TRACE("(%p)->(0x%x %p)\n",iCP,dispId,dispParams); 03102 03103 result = IConnectionPoint_GetConnectionInterface(iCP, &iid); 03104 if (SUCCEEDED(result)) 03105 result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); 03106 else 03107 result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams); 03108 03109 return result; 03110 } 03111 03112 /************************************************************************* 03113 * @ [SHLWAPI.285] 03114 * 03115 * Notify an IConnectionPoint object of changes. 03116 * 03117 * PARAMS 03118 * lpCP [I] Object to notify 03119 * dispID [I] 03120 * 03121 * RETURNS 03122 * Success: S_OK. 03123 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the 03124 * IConnectionPoint interface. 03125 */ 03126 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID) 03127 { 03128 IEnumConnections *lpEnum; 03129 HRESULT hRet = E_NOINTERFACE; 03130 03131 TRACE("(%p,0x%8X)\n", lpCP, dispID); 03132 03133 /* Get an enumerator for the connections */ 03134 if (lpCP) 03135 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum); 03136 03137 if (SUCCEEDED(hRet)) 03138 { 03139 IPropertyNotifySink *lpSink; 03140 CONNECTDATA connData; 03141 ULONG ulFetched; 03142 03143 /* Call OnChanged() for every notify sink in the connection point */ 03144 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK) 03145 { 03146 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) && 03147 lpSink) 03148 { 03149 IPropertyNotifySink_OnChanged(lpSink, dispID); 03150 IPropertyNotifySink_Release(lpSink); 03151 } 03152 IUnknown_Release(connData.pUnk); 03153 } 03154 03155 IEnumConnections_Release(lpEnum); 03156 } 03157 return hRet; 03158 } 03159 03160 /************************************************************************* 03161 * @ [SHLWAPI.286] 03162 * 03163 * IUnknown_CPContainerInvokeParam 03164 */ 03165 HRESULT WINAPIV IUnknown_CPContainerInvokeParam( 03166 IUnknown *container, 03167 REFIID riid, 03168 DISPID dispId, 03169 VARIANTARG* buffer, 03170 DWORD cParams, ...) 03171 { 03172 HRESULT result; 03173 IConnectionPoint *iCP; 03174 IConnectionPointContainer *iCPC; 03175 DISPPARAMS dispParams = {buffer, NULL, cParams, 0}; 03176 __ms_va_list valist; 03177 03178 if (!container) 03179 return E_NOINTERFACE; 03180 03181 result = IUnknown_QueryInterface(container, &IID_IConnectionPointContainer,(LPVOID*) &iCPC); 03182 if (FAILED(result)) 03183 return result; 03184 03185 result = IConnectionPointContainer_FindConnectionPoint(iCPC, riid, &iCP); 03186 IConnectionPointContainer_Release(iCPC); 03187 if(FAILED(result)) 03188 return result; 03189 03190 __ms_va_start(valist, cParams); 03191 SHPackDispParamsV(&dispParams, buffer, cParams, valist); 03192 __ms_va_end(valist); 03193 03194 result = SHLWAPI_InvokeByIID(iCP, riid, dispId, &dispParams); 03195 IConnectionPoint_Release(iCP); 03196 03197 return result; 03198 } 03199 03200 /************************************************************************* 03201 * @ [SHLWAPI.287] 03202 * 03203 * Notify an IConnectionPointContainer object of changes. 03204 * 03205 * PARAMS 03206 * lpUnknown [I] Object to notify 03207 * dispID [I] 03208 * 03209 * RETURNS 03210 * Success: S_OK. 03211 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the 03212 * IConnectionPointContainer interface. 03213 */ 03214 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID) 03215 { 03216 IConnectionPointContainer* lpCPC = NULL; 03217 HRESULT hRet = E_NOINTERFACE; 03218 03219 TRACE("(%p,0x%8X)\n", lpUnknown, dispID); 03220 03221 if (lpUnknown) 03222 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC); 03223 03224 if (SUCCEEDED(hRet)) 03225 { 03226 IConnectionPoint* lpCP; 03227 03228 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP); 03229 IConnectionPointContainer_Release(lpCPC); 03230 03231 hRet = IConnectionPoint_OnChanged(lpCP, dispID); 03232 IConnectionPoint_Release(lpCP); 03233 } 03234 return hRet; 03235 } 03236 03237 /************************************************************************* 03238 * @ [SHLWAPI.289] 03239 * 03240 * See PlaySoundW. 03241 */ 03242 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound) 03243 { 03244 return PlaySoundW(pszSound, hmod, fdwSound); 03245 } 03246 03247 /************************************************************************* 03248 * @ [SHLWAPI.294] 03249 * 03250 * Retrieve a key value from an INI file. See GetPrivateProfileString for 03251 * more information. 03252 * 03253 * PARAMS 03254 * appName [I] The section in the INI file that contains the key 03255 * keyName [I] The key to be retrieved 03256 * out [O] The buffer into which the key's value will be copied 03257 * outLen [I] The length of the `out' buffer 03258 * filename [I] The location of the INI file 03259 * 03260 * RETURNS 03261 * Length of string copied into `out'. 03262 */ 03263 DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, 03264 DWORD outLen, LPCWSTR filename) 03265 { 03266 INT ret; 03267 WCHAR *buf; 03268 03269 TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName), 03270 out, outLen, debugstr_w(filename)); 03271 03272 if(outLen == 0) 03273 return 0; 03274 03275 buf = HeapAlloc(GetProcessHeap(), 0, outLen * sizeof(WCHAR)); 03276 if(!buf){ 03277 *out = 0; 03278 return 0; 03279 } 03280 03281 ret = GetPrivateProfileStringW(appName, keyName, NULL, buf, outLen, filename); 03282 if(ret) 03283 strcpyW(out, buf); 03284 else 03285 *out = 0; 03286 03287 HeapFree(GetProcessHeap(), 0, buf); 03288 03289 return strlenW(out); 03290 } 03291 03292 /************************************************************************* 03293 * @ [SHLWAPI.295] 03294 * 03295 * Set a key value in an INI file. See WritePrivateProfileString for 03296 * more information. 03297 * 03298 * PARAMS 03299 * appName [I] The section in the INI file that contains the key 03300 * keyName [I] The key to be set 03301 * str [O] The value of the key 03302 * filename [I] The location of the INI file 03303 * 03304 * RETURNS 03305 * Success: TRUE 03306 * Failure: FALSE 03307 */ 03308 BOOL WINAPI SHSetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPCWSTR str, 03309 LPCWSTR filename) 03310 { 03311 TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str), 03312 debugstr_w(filename)); 03313 03314 return WritePrivateProfileStringW(appName, keyName, str, filename); 03315 } 03316 03317 /************************************************************************* 03318 * @ [SHLWAPI.313] 03319 * 03320 * See SHGetFileInfoW. 03321 */ 03322 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes, 03323 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags) 03324 { 03325 return SHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags); 03326 } 03327 03328 /************************************************************************* 03329 * @ [SHLWAPI.318] 03330 * 03331 * See DragQueryFileW. 03332 */ 03333 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength) 03334 { 03335 return DragQueryFileW(hDrop, lFile, lpszFile, lLength); 03336 } 03337 03338 /************************************************************************* 03339 * @ [SHLWAPI.333] 03340 * 03341 * See SHBrowseForFolderW. 03342 */ 03343 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi) 03344 { 03345 return SHBrowseForFolderW(lpBi); 03346 } 03347 03348 /************************************************************************* 03349 * @ [SHLWAPI.334] 03350 * 03351 * See SHGetPathFromIDListW. 03352 */ 03353 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath) 03354 { 03355 return SHGetPathFromIDListW(pidl, pszPath); 03356 } 03357 03358 /************************************************************************* 03359 * @ [SHLWAPI.335] 03360 * 03361 * See ShellExecuteExW. 03362 */ 03363 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo) 03364 { 03365 return ShellExecuteExW(lpExecInfo); 03366 } 03367 03368 /************************************************************************* 03369 * @ [SHLWAPI.336] 03370 * 03371 * See SHFileOperationW. 03372 */ 03373 INT WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp) 03374 { 03375 return SHFileOperationW(lpFileOp); 03376 } 03377 03378 /************************************************************************* 03379 * @ [SHLWAPI.342] 03380 * 03381 */ 03382 PVOID WINAPI SHInterlockedCompareExchange( PVOID *dest, PVOID xchg, PVOID compare ) 03383 { 03384 return InterlockedCompareExchangePointer( dest, xchg, compare ); 03385 } 03386 03387 /************************************************************************* 03388 * @ [SHLWAPI.350] 03389 * 03390 * See GetFileVersionInfoSizeW. 03391 */ 03392 DWORD WINAPI GetFileVersionInfoSizeWrapW( LPCWSTR filename, LPDWORD handle ) 03393 { 03394 return GetFileVersionInfoSizeW( filename, handle ); 03395 } 03396 03397 /************************************************************************* 03398 * @ [SHLWAPI.351] 03399 * 03400 * See GetFileVersionInfoW. 03401 */ 03402 BOOL WINAPI GetFileVersionInfoWrapW( LPCWSTR filename, DWORD handle, 03403 DWORD datasize, LPVOID data ) 03404 { 03405 return GetFileVersionInfoW( filename, handle, datasize, data ); 03406 } 03407 03408 /************************************************************************* 03409 * @ [SHLWAPI.352] 03410 * 03411 * See VerQueryValueW. 03412 */ 03413 WORD WINAPI VerQueryValueWrapW( LPVOID pBlock, LPCWSTR lpSubBlock, 03414 LPVOID *lplpBuffer, UINT *puLen ) 03415 { 03416 return VerQueryValueW( pBlock, lpSubBlock, lplpBuffer, puLen ); 03417 } 03418 03419 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj))) 03420 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB 03421 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless) 03422 03423 /************************************************************************* 03424 * @ [SHLWAPI.355] 03425 * 03426 * Change the modality of a shell object. 03427 * 03428 * PARAMS 03429 * lpUnknown [I] Object to make modeless 03430 * bModeless [I] TRUE=Make modeless, FALSE=Make modal 03431 * 03432 * RETURNS 03433 * Success: S_OK. The modality lpUnknown is changed. 03434 * Failure: An HRESULT error code indicating the error. 03435 * 03436 * NOTES 03437 * lpUnknown must support the IOleInPlaceFrame interface, the 03438 * IInternetSecurityMgrSite interface, the IShellBrowser interface 03439 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface, 03440 * or this call will fail. 03441 */ 03442 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless) 03443 { 03444 IUnknown *lpObj; 03445 HRESULT hRet; 03446 03447 TRACE("(%p,%d)\n", lpUnknown, bModeless); 03448 03449 if (!lpUnknown) 03450 return E_FAIL; 03451 03452 if (IsIface(IOleInPlaceActiveObject)) 03453 EnableModeless(IOleInPlaceActiveObject); 03454 else if (IsIface(IOleInPlaceFrame)) 03455 EnableModeless(IOleInPlaceFrame); 03456 else if (IsIface(IShellBrowser)) 03457 EnableModeless(IShellBrowser); 03458 else if (IsIface(IInternetSecurityMgrSite)) 03459 EnableModeless(IInternetSecurityMgrSite); 03460 else if (IsIface(IDocHostUIHandler)) 03461 EnableModeless(IDocHostUIHandler); 03462 else 03463 return hRet; 03464 03465 IUnknown_Release(lpObj); 03466 return S_OK; 03467 } 03468 03469 /************************************************************************* 03470 * @ [SHLWAPI.357] 03471 * 03472 * See SHGetNewLinkInfoW. 03473 */ 03474 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName, 03475 BOOL *pfMustCopy, UINT uFlags) 03476 { 03477 return SHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags); 03478 } 03479 03480 /************************************************************************* 03481 * @ [SHLWAPI.358] 03482 * 03483 * See SHDefExtractIconW. 03484 */ 03485 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge, 03486 HICON* phiconSmall, UINT nIconSize) 03487 { 03488 return SHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize); 03489 } 03490 03491 /************************************************************************* 03492 * @ [SHLWAPI.363] 03493 * 03494 * Get and show a context menu from a shell folder. 03495 * 03496 * PARAMS 03497 * hWnd [I] Window displaying the shell folder 03498 * lpFolder [I] IShellFolder interface 03499 * lpApidl [I] Id for the particular folder desired 03500 * bInvokeDefault [I] Whether to invoke the default menu item 03501 * 03502 * RETURNS 03503 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was 03504 * executed. 03505 * Failure: An HRESULT error code indicating the error. 03506 */ 03507 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault) 03508 { 03509 IContextMenu *iContext; 03510 HRESULT hRet; 03511 03512 TRACE("(%p, %p, %p, %d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault); 03513 03514 if (!lpFolder) 03515 return E_FAIL; 03516 03517 /* Get the context menu from the shell folder */ 03518 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl, 03519 &IID_IContextMenu, 0, (void**)&iContext); 03520 if (SUCCEEDED(hRet)) 03521 { 03522 HMENU hMenu; 03523 if ((hMenu = CreatePopupMenu())) 03524 { 03525 HRESULT hQuery; 03526 DWORD dwDefaultId = 0; 03527 03528 /* Add the context menu entries to the popup */ 03529 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF, 03530 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY); 03531 03532 if (SUCCEEDED(hQuery)) 03533 { 03534 if (bInvokeDefault && 03535 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != (UINT)-1) 03536 { 03537 CMINVOKECOMMANDINFO cmIci; 03538 /* Invoke the default item */ 03539 memset(&cmIci,0,sizeof(cmIci)); 03540 cmIci.cbSize = sizeof(cmIci); 03541 cmIci.fMask = CMIC_MASK_ASYNCOK; 03542 cmIci.hwnd = hWnd; 03543 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId); 03544 cmIci.nShow = SW_SCROLLCHILDREN; 03545 03546 hRet = IContextMenu_InvokeCommand(iContext, &cmIci); 03547 } 03548 } 03549 DestroyMenu(hMenu); 03550 } 03551 IContextMenu_Release(iContext); 03552 } 03553 return hRet; 03554 } 03555 03556 /************************************************************************* 03557 * @ [SHLWAPI.370] 03558 * 03559 * See ExtractIconW. 03560 */ 03561 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName, 03562 UINT nIconIndex) 03563 { 03564 return ExtractIconW(hInstance, lpszExeFileName, nIconIndex); 03565 } 03566 03567 /************************************************************************* 03568 * @ [SHLWAPI.377] 03569 * 03570 * Load a library from the directory of a particular process. 03571 * 03572 * PARAMS 03573 * new_mod [I] Library name 03574 * inst_hwnd [I] Module whose directory is to be used 03575 * dwCrossCodePage [I] Should be FALSE (currently ignored) 03576 * 03577 * RETURNS 03578 * Success: A handle to the loaded module 03579 * Failure: A NULL handle. 03580 */ 03581 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage) 03582 { 03583 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for 03584 * each call here. 03585 * FIXME: Native shows calls to: 03586 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International" 03587 * CheckVersion 03588 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer" 03589 * RegQueryValueExA for "LPKInstalled" 03590 * RegCloseKey 03591 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International" 03592 * RegQueryValueExA for "ResourceLocale" 03593 * RegCloseKey 03594 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}" 03595 * RegQueryValueExA for "Locale" 03596 * RegCloseKey 03597 * and then tests the Locale ("en" for me). 03598 * code below 03599 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done. 03600 */ 03601 CHAR mod_path[2*MAX_PATH]; 03602 LPSTR ptr; 03603 DWORD len; 03604 03605 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwCrossCodePage); 03606 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path)); 03607 if (!len || len >= sizeof(mod_path)) return NULL; 03608 03609 ptr = strrchr(mod_path, '\\'); 03610 if (ptr) { 03611 strcpy(ptr+1, new_mod); 03612 TRACE("loading %s\n", debugstr_a(mod_path)); 03613 return LoadLibraryA(mod_path); 03614 } 03615 return NULL; 03616 } 03617 03618 /************************************************************************* 03619 * @ [SHLWAPI.378] 03620 * 03621 * Unicode version of MLLoadLibraryA. 03622 */ 03623 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage) 03624 { 03625 WCHAR mod_path[2*MAX_PATH]; 03626 LPWSTR ptr; 03627 DWORD len; 03628 03629 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwCrossCodePage); 03630 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR)); 03631 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL; 03632 03633 ptr = strrchrW(mod_path, '\\'); 03634 if (ptr) { 03635 strcpyW(ptr+1, new_mod); 03636 TRACE("loading %s\n", debugstr_w(mod_path)); 03637 return LoadLibraryW(mod_path); 03638 } 03639 return NULL; 03640 } 03641 03642 /************************************************************************* 03643 * ColorAdjustLuma [SHLWAPI.@] 03644 * 03645 * Adjust the luminosity of a color 03646 * 03647 * PARAMS 03648 * cRGB [I] RGB value to convert 03649 * dwLuma [I] Luma adjustment 03650 * bUnknown [I] Unknown 03651 * 03652 * RETURNS 03653 * The adjusted RGB color. 03654 */ 03655 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown) 03656 { 03657 TRACE("(0x%8x,%d,%d)\n", cRGB, dwLuma, bUnknown); 03658 03659 if (dwLuma) 03660 { 03661 WORD wH, wL, wS; 03662 03663 ColorRGBToHLS(cRGB, &wH, &wL, &wS); 03664 03665 FIXME("Ignoring luma adjustment\n"); 03666 03667 /* FIXME: The adjustment is not linear */ 03668 03669 cRGB = ColorHLSToRGB(wH, wL, wS); 03670 } 03671 return cRGB; 03672 } 03673 03674 /************************************************************************* 03675 * @ [SHLWAPI.389] 03676 * 03677 * See GetSaveFileNameW. 03678 */ 03679 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn) 03680 { 03681 return GetSaveFileNameW(ofn); 03682 } 03683 03684 /************************************************************************* 03685 * @ [SHLWAPI.390] 03686 * 03687 * See WNetRestoreConnectionW. 03688 */ 03689 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice) 03690 { 03691 return WNetRestoreConnectionW(hwndOwner, lpszDevice); 03692 } 03693 03694 /************************************************************************* 03695 * @ [SHLWAPI.391] 03696 * 03697 * See WNetGetLastErrorW. 03698 */ 03699 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize, 03700 LPWSTR lpNameBuf, DWORD nNameBufSize) 03701 { 03702 return WNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize); 03703 } 03704 03705 /************************************************************************* 03706 * @ [SHLWAPI.401] 03707 * 03708 * See PageSetupDlgW. 03709 */ 03710 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg) 03711 { 03712 return PageSetupDlgW(pagedlg); 03713 } 03714 03715 /************************************************************************* 03716 * @ [SHLWAPI.402] 03717 * 03718 * See PrintDlgW. 03719 */ 03720 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg) 03721 { 03722 return PrintDlgW(printdlg); 03723 } 03724 03725 /************************************************************************* 03726 * @ [SHLWAPI.403] 03727 * 03728 * See GetOpenFileNameW. 03729 */ 03730 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn) 03731 { 03732 return GetOpenFileNameW(ofn); 03733 } 03734 03735 /************************************************************************* 03736 * @ [SHLWAPI.404] 03737 */ 03738 #if 1 03739 HRESULT WINAPI SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum) 03740 { 03741 /* Windows attempts to get an IPersist interface and, if that fails, an 03742 * IPersistFolder interface on the folder passed-in here. If one of those 03743 * interfaces is available, it then calls GetClassID on the folder... and 03744 * then calls IShellFolder_EnumObjects no matter what, even crashing if 03745 * lpFolder isn't actually an IShellFolder object. The purpose of getting 03746 * the ClassID is unknown, so we don't do it here. 03747 * 03748 * For discussion and detailed tests, see: 03749 * "shlwapi: Be less strict on which type of IShellFolder can be enumerated" 03750 * wine-devel mailing list, 3 Jun 2010 03751 */ 03752 03753 return IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum); 03754 } 03755 #else 03756 HRESULT WINAPI SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum) 03757 { 03758 IPersist *persist; 03759 HRESULT hr; 03760 03761 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist); 03762 if(SUCCEEDED(hr)) 03763 { 03764 CLSID clsid; 03765 hr = IPersist_GetClassID(persist, &clsid); 03766 if(SUCCEEDED(hr)) 03767 { 03768 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder)) 03769 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum); 03770 else 03771 hr = E_FAIL; 03772 } 03773 IPersist_Release(persist); 03774 } 03775 return hr; 03776 } 03777 #endif 03778 03779 /* INTERNAL: Map from HLS color space to RGB */ 03780 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2) 03781 { 03782 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue; 03783 03784 if (wHue > 160) 03785 return wMid1; 03786 else if (wHue > 120) 03787 wHue = 160 - wHue; 03788 else if (wHue > 40) 03789 return wMid2; 03790 03791 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1; 03792 } 03793 03794 /* Convert to RGB and scale into RGB range (0..255) */ 03795 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240 03796 03797 /************************************************************************* 03798 * ColorHLSToRGB [SHLWAPI.@] 03799 * 03800 * Convert from hls color space into an rgb COLORREF. 03801 * 03802 * PARAMS 03803 * wHue [I] Hue amount 03804 * wLuminosity [I] Luminosity amount 03805 * wSaturation [I] Saturation amount 03806 * 03807 * RETURNS 03808 * A COLORREF representing the converted color. 03809 * 03810 * NOTES 03811 * Input hls values are constrained to the range (0..240). 03812 */ 03813 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation) 03814 { 03815 WORD wRed; 03816 03817 if (wSaturation) 03818 { 03819 WORD wGreen, wBlue, wMid1, wMid2; 03820 03821 if (wLuminosity > 120) 03822 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240; 03823 else 03824 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240; 03825 03826 wMid1 = wLuminosity * 2 - wMid2; 03827 03828 wRed = GET_RGB(wHue + 80); 03829 wGreen = GET_RGB(wHue); 03830 wBlue = GET_RGB(wHue - 80); 03831 03832 return RGB(wRed, wGreen, wBlue); 03833 } 03834 03835 wRed = wLuminosity * 255 / 240; 03836 return RGB(wRed, wRed, wRed); 03837 } 03838 03839 /************************************************************************* 03840 * @ [SHLWAPI.413] 03841 * 03842 * Get the current docking status of the system. 03843 * 03844 * PARAMS 03845 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused 03846 * 03847 * RETURNS 03848 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not 03849 * a notebook. 03850 */ 03851 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags) 03852 { 03853 HW_PROFILE_INFOA hwInfo; 03854 03855 TRACE("(0x%08x)\n", dwFlags); 03856 03857 GetCurrentHwProfileA(&hwInfo); 03858 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED)) 03859 { 03860 case DOCKINFO_DOCKED: 03861 case DOCKINFO_UNDOCKED: 03862 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED); 03863 default: 03864 return 0; 03865 } 03866 } 03867 03868 /************************************************************************* 03869 * @ [SHLWAPI.418] 03870 * 03871 * Function seems to do FreeLibrary plus other things. 03872 * 03873 * FIXME native shows the following calls: 03874 * RtlEnterCriticalSection 03875 * LocalFree 03876 * GetProcAddress(Comctl32??, 150L) 03877 * DPA_DeletePtr 03878 * RtlLeaveCriticalSection 03879 * followed by the FreeLibrary. 03880 * The above code may be related to .377 above. 03881 */ 03882 BOOL WINAPI MLFreeLibrary(HMODULE hModule) 03883 { 03884 FIXME("(%p) semi-stub\n", hModule); 03885 return FreeLibrary(hModule); 03886 } 03887 03888 /************************************************************************* 03889 * @ [SHLWAPI.419] 03890 */ 03891 BOOL WINAPI SHFlushSFCacheWrap(void) { 03892 FIXME(": stub\n"); 03893 return TRUE; 03894 } 03895 03896 /************************************************************************* 03897 * @ [SHLWAPI.429] 03898 * FIXME I have no idea what this function does or what its arguments are. 03899 */ 03900 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst) 03901 { 03902 FIXME("(%p) stub\n", hInst); 03903 return FALSE; 03904 } 03905 03906 03907 /************************************************************************* 03908 * @ [SHLWAPI.430] 03909 */ 03910 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap) 03911 { 03912 FIXME("(%p,%p) stub\n", hInst, hHeap); 03913 return E_FAIL; /* This is what is used if shlwapi not loaded */ 03914 } 03915 03916 /************************************************************************* 03917 * @ [SHLWAPI.431] 03918 */ 03919 DWORD WINAPI MLClearMLHInstance(DWORD x) 03920 { 03921 FIXME("(0x%08x)stub\n", x); 03922 return 0xabba1247; 03923 } 03924 03925 /************************************************************************* 03926 * @ [SHLWAPI.432] 03927 * 03928 * See SHSendMessageBroadcastW 03929 * 03930 */ 03931 DWORD WINAPI SHSendMessageBroadcastA(UINT uMsg, WPARAM wParam, LPARAM lParam) 03932 { 03933 return SendMessageTimeoutA(HWND_BROADCAST, uMsg, wParam, lParam, 03934 SMTO_ABORTIFHUNG, 2000, NULL); 03935 } 03936 03937 /************************************************************************* 03938 * @ [SHLWAPI.433] 03939 * 03940 * A wrapper for sending Broadcast Messages to all top level Windows 03941 * 03942 */ 03943 DWORD WINAPI SHSendMessageBroadcastW(UINT uMsg, WPARAM wParam, LPARAM lParam) 03944 { 03945 return SendMessageTimeoutW(HWND_BROADCAST, uMsg, wParam, lParam, 03946 SMTO_ABORTIFHUNG, 2000, NULL); 03947 } 03948 03949 /************************************************************************* 03950 * @ [SHLWAPI.436] 03951 * 03952 * Convert a Unicode string CLSID into a CLSID. 03953 * 03954 * PARAMS 03955 * idstr [I] string containing a CLSID in text form 03956 * id [O] CLSID extracted from the string 03957 * 03958 * RETURNS 03959 * S_OK on success or E_INVALIDARG on failure 03960 */ 03961 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id) 03962 { 03963 return CLSIDFromString((LPCOLESTR)idstr, id); 03964 } 03965 03966 /************************************************************************* 03967 * @ [SHLWAPI.437] 03968 * 03969 * Determine if the OS supports a given feature. 03970 * 03971 * PARAMS 03972 * dwFeature [I] Feature requested (undocumented) 03973 * 03974 * RETURNS 03975 * TRUE If the feature is available. 03976 * FALSE If the feature is not available. 03977 */ 03978 BOOL WINAPI IsOS(DWORD feature) 03979 { 03980 OSVERSIONINFOA osvi; 03981 DWORD platform, majorv, minorv; 03982 03983 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); 03984 if(!GetVersionExA(&osvi)) { 03985 ERR("GetVersionEx failed\n"); 03986 return FALSE; 03987 } 03988 03989 majorv = osvi.dwMajorVersion; 03990 minorv = osvi.dwMinorVersion; 03991 platform = osvi.dwPlatformId; 03992 03993 #define ISOS_RETURN(x) \ 03994 TRACE("(0x%x) ret=%d\n",feature,(x)); \ 03995 return (x); 03996 03997 switch(feature) { 03998 case OS_WIN32SORGREATER: 03999 ISOS_RETURN(platform == VER_PLATFORM_WIN32s 04000 || platform == VER_PLATFORM_WIN32_WINDOWS) 04001 case OS_NT: 04002 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04003 case OS_WIN95ORGREATER: 04004 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS) 04005 case OS_NT4ORGREATER: 04006 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4) 04007 case OS_WIN2000ORGREATER_ALT: 04008 case OS_WIN2000ORGREATER: 04009 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) 04010 case OS_WIN98ORGREATER: 04011 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10) 04012 case OS_WIN98_GOLD: 04013 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10) 04014 case OS_WIN2000PRO: 04015 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) 04016 case OS_WIN2000SERVER: 04017 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) 04018 case OS_WIN2000ADVSERVER: 04019 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) 04020 case OS_WIN2000DATACENTER: 04021 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) 04022 case OS_WIN2000TERMINAL: 04023 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) 04024 case OS_EMBEDDED: 04025 FIXME("(OS_EMBEDDED) What should we return here?\n"); 04026 return FALSE; 04027 case OS_TERMINALCLIENT: 04028 FIXME("(OS_TERMINALCLIENT) What should we return here?\n"); 04029 return FALSE; 04030 case OS_TERMINALREMOTEADMIN: 04031 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n"); 04032 return FALSE; 04033 case OS_WIN95_GOLD: 04034 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0) 04035 case OS_MEORGREATER: 04036 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90) 04037 case OS_XPORGREATER: 04038 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1) 04039 case OS_HOME: 04040 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1) 04041 case OS_PROFESSIONAL: 04042 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04043 case OS_DATACENTER: 04044 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04045 case OS_ADVSERVER: 04046 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) 04047 case OS_SERVER: 04048 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04049 case OS_TERMINALSERVER: 04050 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04051 case OS_PERSONALTERMINALSERVER: 04052 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5) 04053 case OS_FASTUSERSWITCHING: 04054 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n"); 04055 return TRUE; 04056 case OS_WELCOMELOGONUI: 04057 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n"); 04058 return FALSE; 04059 case OS_DOMAINMEMBER: 04060 FIXME("(OS_DOMAINMEMBER) What should we return here?\n"); 04061 return TRUE; 04062 case OS_ANYSERVER: 04063 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04064 case OS_WOW6432: 04065 FIXME("(OS_WOW6432) Should we check this?\n"); 04066 return FALSE; 04067 case OS_WEBSERVER: 04068 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04069 case OS_SMALLBUSINESSSERVER: 04070 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) 04071 case OS_TABLETPC: 04072 FIXME("(OS_TABLEPC) What should we return here?\n"); 04073 return FALSE; 04074 case OS_SERVERADMINUI: 04075 FIXME("(OS_SERVERADMINUI) What should we return here?\n"); 04076 return FALSE; 04077 case OS_MEDIACENTER: 04078 FIXME("(OS_MEDIACENTER) What should we return here?\n"); 04079 return FALSE; 04080 case OS_APPLIANCE: 04081 FIXME("(OS_APPLIANCE) What should we return here?\n"); 04082 return FALSE; 04083 case 0x25: /*OS_VISTAORGREATER*/ 04084 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 6) 04085 } 04086 04087 #undef ISOS_RETURN 04088 04089 WARN("(0x%x) unknown parameter\n",feature); 04090 04091 return FALSE; 04092 } 04093 04094 /************************************************************************* 04095 * @ [SHLWAPI.439] 04096 */ 04097 HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size) 04098 { 04099 DWORD type, sz = size; 04100 04101 if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)buf, &sz) != ERROR_SUCCESS) 04102 return E_FAIL; 04103 04104 return SHLoadIndirectString(buf, buf, size, NULL); 04105 } 04106 04107 /************************************************************************* 04108 * @ [SHLWAPI.478] 04109 * 04110 * Call IInputObject_TranslateAcceleratorIO() on an object. 04111 * 04112 * PARAMS 04113 * lpUnknown [I] Object supporting the IInputObject interface. 04114 * lpMsg [I] Key message to be processed. 04115 * 04116 * RETURNS 04117 * Success: S_OK. 04118 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL. 04119 */ 04120 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg) 04121 { 04122 IInputObject* lpInput = NULL; 04123 HRESULT hRet = E_INVALIDARG; 04124 04125 TRACE("(%p,%p)\n", lpUnknown, lpMsg); 04126 if (lpUnknown) 04127 { 04128 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject, 04129 (void**)&lpInput); 04130 if (SUCCEEDED(hRet) && lpInput) 04131 { 04132 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg); 04133 IInputObject_Release(lpInput); 04134 } 04135 } 04136 return hRet; 04137 } 04138 04139 /************************************************************************* 04140 * @ [SHLWAPI.481] 04141 * 04142 * Call IInputObject_HasFocusIO() on an object. 04143 * 04144 * PARAMS 04145 * lpUnknown [I] Object supporting the IInputObject interface. 04146 * 04147 * RETURNS 04148 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus, 04149 * or S_FALSE otherwise. 04150 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL. 04151 */ 04152 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown) 04153 { 04154 IInputObject* lpInput = NULL; 04155 HRESULT hRet = E_INVALIDARG; 04156 04157 TRACE("(%p)\n", lpUnknown); 04158 if (lpUnknown) 04159 { 04160 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject, 04161 (void**)&lpInput); 04162 if (SUCCEEDED(hRet) && lpInput) 04163 { 04164 hRet = IInputObject_HasFocusIO(lpInput); 04165 IInputObject_Release(lpInput); 04166 } 04167 } 04168 return hRet; 04169 } 04170 04171 /************************************************************************* 04172 * ColorRGBToHLS [SHLWAPI.@] 04173 * 04174 * Convert an rgb COLORREF into the hls color space. 04175 * 04176 * PARAMS 04177 * cRGB [I] Source rgb value 04178 * pwHue [O] Destination for converted hue 04179 * pwLuminance [O] Destination for converted luminance 04180 * pwSaturation [O] Destination for converted saturation 04181 * 04182 * RETURNS 04183 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted 04184 * values. 04185 * 04186 * NOTES 04187 * Output HLS values are constrained to the range (0..240). 04188 * For Achromatic conversions, Hue is set to 160. 04189 */ 04190 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue, 04191 LPWORD pwLuminance, LPWORD pwSaturation) 04192 { 04193 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation; 04194 04195 TRACE("(%08x,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation); 04196 04197 wR = GetRValue(cRGB); 04198 wG = GetGValue(cRGB); 04199 wB = GetBValue(cRGB); 04200 04201 wMax = max(wR, max(wG, wB)); 04202 wMin = min(wR, min(wG, wB)); 04203 04204 /* Luminosity */ 04205 wLuminosity = ((wMax + wMin) * 240 + 255) / 510; 04206 04207 if (wMax == wMin) 04208 { 04209 /* Achromatic case */ 04210 wSaturation = 0; 04211 /* Hue is now unrepresentable, but this is what native returns... */ 04212 wHue = 160; 04213 } 04214 else 04215 { 04216 /* Chromatic case */ 04217 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm; 04218 04219 /* Saturation */ 04220 if (wLuminosity <= 120) 04221 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin); 04222 else 04223 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin); 04224 04225 /* Hue */ 04226 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta; 04227 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta; 04228 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta; 04229 04230 if (wR == wMax) 04231 wHue = wBNorm - wGNorm; 04232 else if (wG == wMax) 04233 wHue = 80 + wRNorm - wBNorm; 04234 else 04235 wHue = 160 + wGNorm - wRNorm; 04236 if (wHue < 0) 04237 wHue += 240; 04238 else if (wHue > 240) 04239 wHue -= 240; 04240 } 04241 if (pwHue) 04242 *pwHue = wHue; 04243 if (pwLuminance) 04244 *pwLuminance = wLuminosity; 04245 if (pwSaturation) 04246 *pwSaturation = wSaturation; 04247 } 04248 04249 /************************************************************************* 04250 * SHCreateShellPalette [SHLWAPI.@] 04251 */ 04252 HPALETTE WINAPI SHCreateShellPalette(HDC hdc) 04253 { 04254 FIXME("stub\n"); 04255 return CreateHalftonePalette(hdc); 04256 } 04257 04258 /************************************************************************* 04259 * SHGetInverseCMAP (SHLWAPI.@) 04260 * 04261 * Get an inverse color map table. 04262 * 04263 * PARAMS 04264 * lpCmap [O] Destination for color map 04265 * dwSize [I] Size of memory pointed to by lpCmap 04266 * 04267 * RETURNS 04268 * Success: S_OK. 04269 * Failure: E_POINTER, If lpCmap is invalid. 04270 * E_INVALIDARG, If dwFlags is invalid 04271 * E_OUTOFMEMORY, If there is no memory available 04272 * 04273 * NOTES 04274 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192). 04275 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's 04276 * internal CMap. 04277 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from 04278 * this DLL's internal CMap. 04279 */ 04280 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize) 04281 { 04282 if (dwSize == 4) { 04283 FIXME(" - returning bogus address for SHGetInverseCMAP\n"); 04284 *dest = (DWORD)0xabba1249; 04285 return 0; 04286 } 04287 FIXME("(%p, %#x) stub\n", dest, dwSize); 04288 return 0; 04289 } 04290 04291 /************************************************************************* 04292 * SHIsLowMemoryMachine [SHLWAPI.@] 04293 * 04294 * Determine if the current computer has low memory. 04295 * 04296 * PARAMS 04297 * x [I] FIXME 04298 * 04299 * RETURNS 04300 * TRUE if the users machine has 16 Megabytes of memory or less, 04301 * FALSE otherwise. 04302 */ 04303 BOOL WINAPI SHIsLowMemoryMachine (DWORD x) 04304 { 04305 FIXME("(0x%08x) stub\n", x); 04306 return FALSE; 04307 } 04308 04309 /************************************************************************* 04310 * GetMenuPosFromID [SHLWAPI.@] 04311 * 04312 * Return the position of a menu item from its Id. 04313 * 04314 * PARAMS 04315 * hMenu [I] Menu containing the item 04316 * wID [I] Id of the menu item 04317 * 04318 * RETURNS 04319 * Success: The index of the menu item in hMenu. 04320 * Failure: -1, If the item is not found. 04321 */ 04322 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID) 04323 { 04324 MENUITEMINFOW mi; 04325 INT nCount = GetMenuItemCount(hMenu), nIter = 0; 04326 04327 TRACE("%p %u\n", hMenu, wID); 04328 04329 while (nIter < nCount) 04330 { 04331 mi.cbSize = sizeof(mi); 04332 mi.fMask = MIIM_ID; 04333 if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID) 04334 { 04335 TRACE("ret %d\n", nIter); 04336 return nIter; 04337 } 04338 nIter++; 04339 } 04340 04341 return -1; 04342 } 04343 04344 /************************************************************************* 04345 * @ [SHLWAPI.179] 04346 * 04347 * Same as SHLWAPI.GetMenuPosFromID 04348 */ 04349 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID) 04350 { 04351 TRACE("%p %u\n", hMenu, uID); 04352 return GetMenuPosFromID(hMenu, uID); 04353 } 04354 04355 04356 /************************************************************************* 04357 * @ [SHLWAPI.448] 04358 */ 04359 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr) 04360 { 04361 while (*lpwstr) 04362 { 04363 if (*lpwstr == '/') 04364 *lpwstr = '\\'; 04365 lpwstr++; 04366 } 04367 } 04368 04369 04370 /************************************************************************* 04371 * @ [SHLWAPI.461] 04372 */ 04373 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown) 04374 { 04375 FIXME("(0x%08x) stub\n", dwUnknown); 04376 return 0; 04377 } 04378 04379 04380 /************************************************************************* 04381 * @ [SHLWAPI.549] 04382 */ 04383 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter, 04384 DWORD dwClsContext, REFIID iid, LPVOID *ppv) 04385 { 04386 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv); 04387 } 04388 04389 /************************************************************************* 04390 * SHSkipJunction [SHLWAPI.@] 04391 * 04392 * Determine if a bind context can be bound to an object 04393 * 04394 * PARAMS 04395 * pbc [I] Bind context to check 04396 * pclsid [I] CLSID of object to be bound to 04397 * 04398 * RETURNS 04399 * TRUE: If it is safe to bind 04400 * FALSE: If pbc is invalid or binding would not be safe 04401 * 04402 */ 04403 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid) 04404 { 04405 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ', 04406 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' }; 04407 BOOL bRet = FALSE; 04408 04409 if (pbc) 04410 { 04411 IUnknown* lpUnk; 04412 04413 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk))) 04414 { 04415 CLSID clsid; 04416 04417 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) && 04418 IsEqualGUID(pclsid, &clsid)) 04419 bRet = TRUE; 04420 04421 IUnknown_Release(lpUnk); 04422 } 04423 } 04424 return bRet; 04425 } 04426 04427 /*********************************************************************** 04428 * SHGetShellKey (SHLWAPI.@) 04429 */ 04430 HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create) 04431 { 04432 FIXME("(0x%08x, %s, %d): stub\n", flags, debugstr_w(sub_key), create); 04433 return (HKEY)0x50; 04434 } 04435 04436 /*********************************************************************** 04437 * SHQueueUserWorkItem (SHLWAPI.@) 04438 */ 04439 BOOL WINAPI SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback, 04440 LPVOID pContext, LONG lPriority, DWORD_PTR dwTag, 04441 DWORD_PTR *pdwId, LPCSTR pszModule, DWORD dwFlags) 04442 { 04443 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback, pContext, 04444 lPriority, dwTag, pdwId, debugstr_a(pszModule), dwFlags); 04445 04446 if(lPriority || dwTag || pdwId || pszModule || dwFlags) 04447 FIXME("Unsupported arguments\n"); 04448 04449 return QueueUserWorkItem(pfnCallback, pContext, 0); 04450 } 04451 04452 /*********************************************************************** 04453 * SHSetTimerQueueTimer (SHLWAPI.263) 04454 */ 04455 HANDLE WINAPI SHSetTimerQueueTimer(HANDLE hQueue, 04456 WAITORTIMERCALLBACK pfnCallback, LPVOID pContext, DWORD dwDueTime, 04457 DWORD dwPeriod, LPCSTR lpszLibrary, DWORD dwFlags) 04458 { 04459 HANDLE hNewTimer; 04460 04461 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */ 04462 if (dwFlags & TPS_LONGEXECTIME) { 04463 dwFlags &= ~TPS_LONGEXECTIME; 04464 dwFlags |= WT_EXECUTELONGFUNCTION; 04465 } 04466 if (dwFlags & TPS_EXECUTEIO) { 04467 dwFlags &= ~TPS_EXECUTEIO; 04468 dwFlags |= WT_EXECUTEINIOTHREAD; 04469 } 04470 04471 if (!CreateTimerQueueTimer(&hNewTimer, hQueue, pfnCallback, pContext, 04472 dwDueTime, dwPeriod, dwFlags)) 04473 return NULL; 04474 04475 return hNewTimer; 04476 } 04477 04478 /*********************************************************************** 04479 * IUnknown_OnFocusChangeIS (SHLWAPI.@) 04480 */ 04481 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus) 04482 { 04483 IInputObjectSite *pIOS = NULL; 04484 HRESULT hRet = E_INVALIDARG; 04485 04486 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE"); 04487 04488 if (lpUnknown) 04489 { 04490 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite, 04491 (void **)&pIOS); 04492 if (SUCCEEDED(hRet) && pIOS) 04493 { 04494 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus); 04495 IInputObjectSite_Release(pIOS); 04496 } 04497 } 04498 return hRet; 04499 } 04500 04501 /*********************************************************************** 04502 * SHGetValueW (SHLWAPI.@) 04503 */ 04504 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f) 04505 { 04506 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f); 04507 return E_FAIL; 04508 } 04509 04510 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *); 04511 04512 /*********************************************************************** 04513 * GetUIVersion (SHLWAPI.452) 04514 */ 04515 DWORD WINAPI GetUIVersion(void) 04516 { 04517 static DWORD version; 04518 04519 if (!version) 04520 { 04521 DllGetVersion_func pDllGetVersion; 04522 HMODULE dll = LoadLibraryA("shell32.dll"); 04523 if (!dll) return 0; 04524 04525 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion"); 04526 if (pDllGetVersion) 04527 { 04528 DLLVERSIONINFO dvi; 04529 dvi.cbSize = sizeof(DLLVERSIONINFO); 04530 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion; 04531 } 04532 FreeLibrary( dll ); 04533 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */ 04534 } 04535 return version; 04536 } 04537 04538 /*********************************************************************** 04539 * ShellMessageBoxWrapW [SHLWAPI.388] 04540 * 04541 * See shell32.ShellMessageBoxW 04542 * 04543 * NOTE: 04544 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW 04545 * because we can't forward to it in the .spec file since it's exported by 04546 * ordinal. If you change the implementation here please update the code in 04547 * shell32 as well. 04548 */ 04549 INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText, 04550 LPCWSTR lpCaption, UINT uType, ...) 04551 { 04552 WCHAR *szText = NULL, szTitle[100]; 04553 LPCWSTR pszText, pszTitle = szTitle; 04554 LPWSTR pszTemp; 04555 __ms_va_list args; 04556 int ret; 04557 04558 __ms_va_start(args, uType); 04559 04560 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance, hWnd, lpText, lpCaption, uType); 04561 04562 if (IS_INTRESOURCE(lpCaption)) 04563 LoadStringW(hInstance, LOWORD(lpCaption), szTitle, sizeof(szTitle)/sizeof(szTitle[0])); 04564 else 04565 pszTitle = lpCaption; 04566 04567 if (IS_INTRESOURCE(lpText)) 04568 { 04569 const WCHAR *ptr; 04570 UINT len = LoadStringW(hInstance, LOWORD(lpText), (LPWSTR)&ptr, 0); 04571 04572 if (len) 04573 { 04574 szText = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); 04575 if (szText) LoadStringW(hInstance, LOWORD(lpText), szText, len + 1); 04576 } 04577 pszText = szText; 04578 if (!pszText) { 04579 WARN("Failed to load id %d\n", LOWORD(lpText)); 04580 __ms_va_end(args); 04581 return 0; 04582 } 04583 } 04584 else 04585 pszText = lpText; 04586 04587 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, 04588 pszText, 0, 0, (LPWSTR)&pszTemp, 0, &args); 04589 04590 __ms_va_end(args); 04591 04592 ret = MessageBoxW(hWnd, pszTemp, pszTitle, uType); 04593 04594 HeapFree(GetProcessHeap(), 0, szText); 04595 LocalFree(pszTemp); 04596 return ret; 04597 } 04598 04599 /*********************************************************************** 04600 * ZoneComputePaneSize [SHLWAPI.382] 04601 */ 04602 UINT WINAPI ZoneComputePaneSize(HWND hwnd) 04603 { 04604 FIXME("\n"); 04605 return 0x95; 04606 } 04607 04608 /*********************************************************************** 04609 * SHChangeNotifyWrap [SHLWAPI.394] 04610 */ 04611 void WINAPI SHChangeNotifyWrap(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) 04612 { 04613 SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2); 04614 } 04615 04616 typedef struct SHELL_USER_SID { /* according to MSDN this should be in shlobj.h... */ 04617 SID_IDENTIFIER_AUTHORITY sidAuthority; 04618 DWORD dwUserGroupID; 04619 DWORD dwUserID; 04620 } SHELL_USER_SID, *PSHELL_USER_SID; 04621 04622 typedef struct SHELL_USER_PERMISSION { /* ...and this should be in shlwapi.h */ 04623 SHELL_USER_SID susID; 04624 DWORD dwAccessType; 04625 BOOL fInherit; 04626 DWORD dwAccessMask; 04627 DWORD dwInheritMask; 04628 DWORD dwInheritAccessMask; 04629 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION; 04630 04631 /*********************************************************************** 04632 * GetShellSecurityDescriptor [SHLWAPI.475] 04633 * 04634 * prepares SECURITY_DESCRIPTOR from a set of ACEs 04635 * 04636 * PARAMS 04637 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures, 04638 * each of which describes permissions to apply 04639 * cUserPerm [I] number of entries in apUserPerm array 04640 * 04641 * RETURNS 04642 * success: pointer to SECURITY_DESCRIPTOR 04643 * failure: NULL 04644 * 04645 * NOTES 04646 * Call should free returned descriptor with LocalFree 04647 */ 04648 PSECURITY_DESCRIPTOR WINAPI GetShellSecurityDescriptor(PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm) 04649 { 04650 PSID *sidlist; 04651 PSID cur_user = NULL; 04652 BYTE tuUser[2000]; 04653 DWORD acl_size; 04654 int sid_count, i; 04655 PSECURITY_DESCRIPTOR psd = NULL; 04656 04657 TRACE("%p %d\n", apUserPerm, cUserPerm); 04658 04659 if (apUserPerm == NULL || cUserPerm <= 0) 04660 return NULL; 04661 04662 sidlist = HeapAlloc(GetProcessHeap(), 0, cUserPerm * sizeof(PSID)); 04663 if (!sidlist) 04664 return NULL; 04665 04666 acl_size = sizeof(ACL); 04667 04668 for(sid_count = 0; sid_count < cUserPerm; sid_count++) 04669 { 04670 static SHELL_USER_SID null_sid = {{SECURITY_NULL_SID_AUTHORITY}, 0, 0}; 04671 PSHELL_USER_PERMISSION perm = apUserPerm[sid_count]; 04672 PSHELL_USER_SID sid = &perm->susID; 04673 PSID pSid; 04674 BOOL ret = TRUE; 04675 04676 if (!memcmp((void*)sid, (void*)&null_sid, sizeof(SHELL_USER_SID))) 04677 { /* current user's SID */ 04678 if (!cur_user) 04679 { 04680 HANDLE Token; 04681 DWORD bufsize = sizeof(tuUser); 04682 04683 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token); 04684 if (ret) 04685 { 04686 ret = GetTokenInformation(Token, TokenUser, (void*)tuUser, bufsize, &bufsize ); 04687 if (ret) 04688 cur_user = ((PTOKEN_USER)tuUser)->User.Sid; 04689 CloseHandle(Token); 04690 } 04691 } 04692 pSid = cur_user; 04693 } else if (sid->dwUserID==0) /* one sub-authority */ 04694 ret = AllocateAndInitializeSid(&sid->sidAuthority, 1, sid->dwUserGroupID, 0, 04695 0, 0, 0, 0, 0, 0, &pSid); 04696 else 04697 ret = AllocateAndInitializeSid(&sid->sidAuthority, 2, sid->dwUserGroupID, sid->dwUserID, 04698 0, 0, 0, 0, 0, 0, &pSid); 04699 if (!ret) 04700 goto free_sids; 04701 04702 sidlist[sid_count] = pSid; 04703 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */ 04704 acl_size += (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + GetLengthSid(pSid)) * (perm->fInherit ? 2 : 1); 04705 } 04706 04707 psd = LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR) + acl_size); 04708 04709 if (psd != NULL) 04710 { 04711 PACL pAcl = (PACL)(((BYTE*)psd)+sizeof(SECURITY_DESCRIPTOR)); 04712 04713 if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)) 04714 goto error; 04715 04716 if (!InitializeAcl(pAcl, acl_size, ACL_REVISION)) 04717 goto error; 04718 04719 for(i = 0; i < sid_count; i++) 04720 { 04721 PSHELL_USER_PERMISSION sup = apUserPerm[i]; 04722 PSID sid = sidlist[i]; 04723 04724 switch(sup->dwAccessType) 04725 { 04726 case ACCESS_ALLOWED_ACE_TYPE: 04727 if (!AddAccessAllowedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid)) 04728 goto error; 04729 if (sup->fInherit && !AddAccessAllowedAceEx(pAcl, ACL_REVISION, 04730 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid)) 04731 goto error; 04732 break; 04733 case ACCESS_DENIED_ACE_TYPE: 04734 if (!AddAccessDeniedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid)) 04735 goto error; 04736 if (sup->fInherit && !AddAccessDeniedAceEx(pAcl, ACL_REVISION, 04737 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid)) 04738 goto error; 04739 break; 04740 default: 04741 goto error; 04742 } 04743 } 04744 04745 if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE)) 04746 goto error; 04747 } 04748 goto free_sids; 04749 04750 error: 04751 LocalFree(psd); 04752 psd = NULL; 04753 free_sids: 04754 for(i = 0; i < sid_count; i++) 04755 { 04756 if (!cur_user || sidlist[i] != cur_user) 04757 FreeSid(sidlist[i]); 04758 } 04759 HeapFree(GetProcessHeap(), 0, sidlist); 04760 04761 return psd; 04762 } 04763 04764 /*********************************************************************** 04765 * SHCreatePropertyBagOnRegKey [SHLWAPI.471] 04766 * 04767 * Creates a property bag from a registry key 04768 * 04769 * PARAMS 04770 * hKey [I] Handle to the desired registry key 04771 * subkey [I] Name of desired subkey, or NULL to open hKey directly 04772 * grfMode [I] Optional flags 04773 * riid [I] IID of requested property bag interface 04774 * ppv [O] Address to receive pointer to the new interface 04775 * 04776 * RETURNS 04777 * success: 0 04778 * failure: error code 04779 * 04780 */ 04781 HRESULT WINAPI SHCreatePropertyBagOnRegKey (HKEY hKey, LPCWSTR subkey, 04782 DWORD grfMode, REFIID riid, void **ppv) 04783 { 04784 FIXME("%p %s %d %s %p STUB\n", hKey, debugstr_w(subkey), grfMode, 04785 debugstr_guid(riid), ppv); 04786 04787 return E_NOTIMPL; 04788 } 04789 04790 /*********************************************************************** 04791 * SHGetViewStatePropertyBag [SHLWAPI.515] 04792 * 04793 * Retrieves a property bag in which the view state information of a folder 04794 * can be stored. 04795 * 04796 * PARAMS 04797 * pidl [I] PIDL of the folder requested 04798 * bag_name [I] Name of the property bag requested 04799 * flags [I] Optional flags 04800 * riid [I] IID of requested property bag interface 04801 * ppv [O] Address to receive pointer to the new interface 04802 * 04803 * RETURNS 04804 * success: S_OK 04805 * failure: error code 04806 * 04807 */ 04808 HRESULT WINAPI SHGetViewStatePropertyBag(LPCITEMIDLIST pidl, LPWSTR bag_name, 04809 DWORD flags, REFIID riid, void **ppv) 04810 { 04811 FIXME("%p %s %d %s %p STUB\n", pidl, debugstr_w(bag_name), flags, 04812 debugstr_guid(riid), ppv); 04813 04814 return E_NOTIMPL; 04815 } 04816 04817 /*********************************************************************** 04818 * SHFormatDateTimeW [SHLWAPI.354] 04819 * 04820 * Produces a string representation of a time. 04821 * 04822 * PARAMS 04823 * fileTime [I] Pointer to FILETIME structure specifying the time 04824 * flags [I] Flags specifying the desired output 04825 * buf [O] Pointer to buffer for output 04826 * size [I] Number of characters that can be contained in buffer 04827 * 04828 * RETURNS 04829 * success: number of characters written to the buffer 04830 * failure: 0 04831 * 04832 */ 04833 INT WINAPI SHFormatDateTimeW(const FILETIME UNALIGNED *fileTime, DWORD *flags, 04834 LPWSTR buf, UINT size) 04835 { 04836 #define SHFORMATDT_UNSUPPORTED_FLAGS (FDTF_RELATIVE | FDTF_LTRDATE | FDTF_RTLDATE | FDTF_NOAUTOREADINGORDER) 04837 DWORD fmt_flags = flags ? *flags : FDTF_DEFAULT; 04838 SYSTEMTIME st; 04839 FILETIME ft; 04840 INT ret = 0; 04841 04842 TRACE("%p %p %p %u\n", fileTime, flags, buf, size); 04843 04844 if (!buf || !size) 04845 return 0; 04846 04847 if (fmt_flags & SHFORMATDT_UNSUPPORTED_FLAGS) 04848 FIXME("ignoring some flags - 0x%08x\n", fmt_flags & SHFORMATDT_UNSUPPORTED_FLAGS); 04849 04850 FileTimeToLocalFileTime(fileTime, &ft); 04851 FileTimeToSystemTime(&ft, &st); 04852 04853 /* first of all date */ 04854 if (fmt_flags & (FDTF_LONGDATE | FDTF_SHORTDATE)) 04855 { 04856 static const WCHAR sep1[] = {',',' ',0}; 04857 static const WCHAR sep2[] = {' ',0}; 04858 04859 DWORD date = fmt_flags & FDTF_LONGDATE ? DATE_LONGDATE : DATE_SHORTDATE; 04860 ret = GetDateFormatW(LOCALE_USER_DEFAULT, date, &st, NULL, buf, size); 04861 if (ret >= size) return ret; 04862 04863 /* add separator */ 04864 if (ret < size && (fmt_flags & (FDTF_LONGTIME | FDTF_SHORTTIME))) 04865 { 04866 if ((fmt_flags & FDTF_LONGDATE) && (ret < size + 2)) 04867 { 04868 if (ret < size + 2) 04869 { 04870 lstrcatW(&buf[ret-1], sep1); 04871 ret += 2; 04872 } 04873 } 04874 else 04875 { 04876 lstrcatW(&buf[ret-1], sep2); 04877 ret++; 04878 } 04879 } 04880 } 04881 /* time part */ 04882 if (fmt_flags & (FDTF_LONGTIME | FDTF_SHORTTIME)) 04883 { 04884 DWORD time = fmt_flags & FDTF_LONGTIME ? 0 : TIME_NOSECONDS; 04885 04886 if (ret) ret--; 04887 ret += GetTimeFormatW(LOCALE_USER_DEFAULT, time, &st, NULL, &buf[ret], size - ret); 04888 } 04889 04890 return ret; 04891 04892 #undef SHFORMATDT_UNSUPPORTED_FLAGS 04893 } 04894 04895 /*********************************************************************** 04896 * SHFormatDateTimeA [SHLWAPI.353] 04897 * 04898 * See SHFormatDateTimeW. 04899 * 04900 */ 04901 INT WINAPI SHFormatDateTimeA(const FILETIME UNALIGNED *fileTime, DWORD *flags, 04902 LPSTR buf, UINT size) 04903 { 04904 WCHAR *bufW; 04905 INT retval; 04906 04907 if (!buf || !size) 04908 return 0; 04909 04910 bufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * size); 04911 retval = SHFormatDateTimeW(fileTime, flags, bufW, size); 04912 04913 if (retval != 0) 04914 WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, size, NULL, NULL); 04915 04916 HeapFree(GetProcessHeap(), 0, bufW); 04917 return retval; 04918 } 04919 04920 /*********************************************************************** 04921 * ZoneCheckUrlExW [SHLWAPI.231] 04922 * 04923 * Checks the details of the security zone for the supplied site. (?) 04924 * 04925 * PARAMS 04926 * 04927 * szURL [I] Pointer to the URL to check 04928 * 04929 * Other parameters currently unknown. 04930 * 04931 * RETURNS 04932 * unknown 04933 */ 04934 04935 INT WINAPI ZoneCheckUrlExW(LPWSTR szURL, PVOID pUnknown, DWORD dwUnknown2, 04936 DWORD dwUnknown3, DWORD dwUnknown4, DWORD dwUnknown5, DWORD dwUnknown6, 04937 DWORD dwUnknown7) 04938 { 04939 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL), pUnknown, dwUnknown2, 04940 dwUnknown3, dwUnknown4, dwUnknown5, dwUnknown6, dwUnknown7); 04941 04942 return 0; 04943 } 04944 04945 /*********************************************************************** 04946 * SHVerbExistsNA [SHLWAPI.196] 04947 * 04948 * 04949 * PARAMS 04950 * 04951 * verb [I] a string, often appears to be an extension. 04952 * 04953 * Other parameters currently unknown. 04954 * 04955 * RETURNS 04956 * unknown 04957 */ 04958 INT WINAPI SHVerbExistsNA(LPSTR verb, PVOID pUnknown, PVOID pUnknown2, DWORD dwUnknown3) 04959 { 04960 FIXME("(%s, %p, %p, %i) STUB\n",verb, pUnknown, pUnknown2, dwUnknown3); 04961 return 0; 04962 } 04963 04964 /************************************************************************* 04965 * @ [SHLWAPI.538] 04966 * 04967 * Undocumented: Implementation guessed at via Name and behavior 04968 * 04969 * PARAMS 04970 * lpUnknown [I] Object to get an IServiceProvider interface from 04971 * riid [I] Function requested for QueryService call 04972 * lppOut [O] Destination for the service interface pointer 04973 * 04974 * RETURNS 04975 * Success: S_OK. lppOut contains an object providing the requested service 04976 * Failure: An HRESULT error code 04977 * 04978 * NOTES 04979 * lpUnknown is expected to support the IServiceProvider interface. 04980 */ 04981 HRESULT WINAPI IUnknown_QueryServiceForWebBrowserApp(IUnknown* lpUnknown, 04982 REFGUID riid, LPVOID *lppOut) 04983 { 04984 FIXME("%p %s %p semi-STUB\n", lpUnknown, debugstr_guid(riid), lppOut); 04985 return IUnknown_QueryService(lpUnknown,&IID_IWebBrowserApp,riid,lppOut); 04986 } 04987 04988 /************************************************************************** 04989 * SHPropertyBag_ReadLONG (SHLWAPI.496) 04990 * 04991 * This function asks a property bag to read a named property as a LONG. 04992 * 04993 * PARAMS 04994 * ppb: a IPropertyBag interface 04995 * pszPropName: Unicode string that names the property 04996 * pValue: address to receive the property value as a 32-bit signed integer 04997 * 04998 * RETURNS 04999 * 0 for Success 05000 */ 05001 BOOL WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLONG pValue) 05002 { 05003 VARIANT var; 05004 HRESULT hr; 05005 TRACE("%p %s %p\n", ppb,debugstr_w(pszPropName),pValue); 05006 if (!pszPropName || !ppb || !pValue) 05007 return E_INVALIDARG; 05008 V_VT(&var) = VT_I4; 05009 hr = IPropertyBag_Read(ppb, pszPropName, &var, NULL); 05010 if (SUCCEEDED(hr)) 05011 { 05012 if (V_VT(&var) == VT_I4) 05013 *pValue = V_I4(&var); 05014 else 05015 hr = DISP_E_BADVARTYPE; 05016 } 05017 return hr; 05018 } 05019 05020 /* return flags for SHGetObjectCompatFlags, names derived from registry value names */ 05021 #define OBJCOMPAT_OTNEEDSSFCACHE 0x00000001 05022 #define OBJCOMPAT_NO_WEBVIEW 0x00000002 05023 #define OBJCOMPAT_UNBINDABLE 0x00000004 05024 #define OBJCOMPAT_PINDLL 0x00000008 05025 #define OBJCOMPAT_NEEDSFILESYSANCESTOR 0x00000010 05026 #define OBJCOMPAT_NOTAFILESYSTEM 0x00000020 05027 #define OBJCOMPAT_CTXMENU_NOVERBS 0x00000040 05028 #define OBJCOMPAT_CTXMENU_LIMITEDQI 0x00000080 05029 #define OBJCOMPAT_COCREATESHELLFOLDERONLY 0x00000100 05030 #define OBJCOMPAT_NEEDSSTORAGEANCESTOR 0x00000200 05031 #define OBJCOMPAT_NOLEGACYWEBVIEW 0x00000400 05032 #define OBJCOMPAT_CTXMENU_XPQCMFLAGS 0x00001000 05033 #define OBJCOMPAT_NOIPROPERTYSTORE 0x00002000 05034 05035 /* a search table for compatibility flags */ 05036 struct objcompat_entry { 05037 const WCHAR name[30]; 05038 DWORD value; 05039 }; 05040 05041 /* expected to be sorted by name */ 05042 static const struct objcompat_entry objcompat_table[] = { 05043 { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0}, 05044 OBJCOMPAT_COCREATESHELLFOLDERONLY }, 05045 { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0}, 05046 OBJCOMPAT_CTXMENU_LIMITEDQI }, 05047 { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0}, 05048 OBJCOMPAT_CTXMENU_LIMITEDQI }, 05049 { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0}, 05050 OBJCOMPAT_CTXMENU_XPQCMFLAGS }, 05051 { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0}, 05052 OBJCOMPAT_NEEDSFILESYSANCESTOR }, 05053 { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0}, 05054 OBJCOMPAT_NEEDSSTORAGEANCESTOR }, 05055 { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0}, 05056 OBJCOMPAT_NOIPROPERTYSTORE }, 05057 { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0}, 05058 OBJCOMPAT_NOLEGACYWEBVIEW }, 05059 { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0}, 05060 OBJCOMPAT_NOTAFILESYSTEM }, 05061 { {'N','O','_','W','E','B','V','I','E','W',0}, 05062 OBJCOMPAT_NO_WEBVIEW }, 05063 { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0}, 05064 OBJCOMPAT_OTNEEDSSFCACHE }, 05065 { {'P','I','N','D','L','L',0}, 05066 OBJCOMPAT_PINDLL }, 05067 { {'U','N','B','I','N','D','A','B','L','E',0}, 05068 OBJCOMPAT_UNBINDABLE } 05069 }; 05070 05071 /************************************************************************** 05072 * SHGetObjectCompatFlags (SHLWAPI.476) 05073 * 05074 * Function returns an integer representation of compatibility flags stored 05075 * in registry for CLSID under ShellCompatibility subkey. 05076 * 05077 * PARAMS 05078 * pUnk: pointer to object IUnknown interface, idetifies CLSID 05079 * clsid: pointer to CLSID to retrieve data for 05080 * 05081 * RETURNS 05082 * 0 on failure, flags set on success 05083 */ 05084 DWORD WINAPI SHGetObjectCompatFlags(IUnknown *pUnk, const CLSID *clsid) 05085 { 05086 static const WCHAR compatpathW[] = 05087 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 05088 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 05089 'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\', 05090 'O','b','j','e','c','t','s','\\','%','s',0}; 05091 WCHAR strW[sizeof(compatpathW)/sizeof(WCHAR) + 38 /* { CLSID } */]; 05092 DWORD ret, length = sizeof(strW)/sizeof(WCHAR); 05093 OLECHAR *clsid_str; 05094 HKEY key; 05095 INT i; 05096 05097 TRACE("%p %s\n", pUnk, debugstr_guid(clsid)); 05098 05099 if (!pUnk && !clsid) return 0; 05100 05101 if (pUnk && !clsid) 05102 { 05103 FIXME("iface not handled\n"); 05104 return 0; 05105 } 05106 05107 StringFromCLSID(clsid, &clsid_str); 05108 sprintfW(strW, compatpathW, clsid_str); 05109 CoTaskMemFree(clsid_str); 05110 05111 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, strW, &key); 05112 if (ret != ERROR_SUCCESS) return 0; 05113 05114 /* now collect flag values */ 05115 ret = 0; 05116 for (i = 0; RegEnumValueW(key, i, strW, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; i++) 05117 { 05118 INT left, right, res, x; 05119 05120 /* search in table */ 05121 left = 0; 05122 right = sizeof(objcompat_table) / sizeof(struct objcompat_entry) - 1; 05123 05124 while (right >= left) { 05125 x = (left + right) / 2; 05126 res = strcmpW(strW, objcompat_table[x].name); 05127 if (res == 0) 05128 { 05129 ret |= objcompat_table[x].value; 05130 break; 05131 } 05132 else if (res < 0) 05133 right = x - 1; 05134 else 05135 left = x + 1; 05136 } 05137 05138 length = sizeof(strW)/sizeof(WCHAR); 05139 } 05140 05141 return ret; 05142 } Generated on Wed May 23 2012 04:24:27 for ReactOS by
1.7.6.1
|