Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

482 lines
13 KiB

  1. #include "pch.h"
  2. #include <advpub.h> // For REGINSTALL
  3. #pragma hdrstop
  4. /*-----------------------------------------------------------------------------
  5. / GetKeyForCLSID
  6. / --------------
  7. / Given a reference to a CLSID open up the key that represents it.
  8. /
  9. / In:
  10. / clsid = clsid reference
  11. / pSubKey -> name of sub key to be opened
  12. / phkey = receives the newly opened key
  13. /
  14. / Out:
  15. / HRESULT
  16. /----------------------------------------------------------------------------*/
  17. EXTERN_C HRESULT GetKeyForCLSID(REFCLSID clsid, LPCTSTR pSubKey, HKEY* phkey)
  18. {
  19. HRESULT hr;
  20. TCHAR szBuffer[(MAX_PATH*2)+GUIDSTR_MAX];
  21. TCHAR szGuid[GUIDSTR_MAX];
  22. TraceEnter(TRACE_COMMON_MISC, "GetKeyForCLSID");
  23. TraceGUID("clsid", clsid);
  24. Trace(TEXT("pSubKey -%s-"), pSubKey ? pSubKey:TEXT("<none>"));
  25. TraceAssert(phkey);
  26. // - format the CLSID so we can find it in the registry
  27. // - then open it (the client is reponsible for closing it)
  28. *phkey = NULL; // incase we fail
  29. if ( 0 == GetStringFromGUID(clsid, szGuid, ARRAYSIZE(szGuid)) )
  30. ExitGracefully(hr, E_FAIL, "Failed to convert GUID to string");
  31. wnsprintf(szBuffer, ARRAYSIZE(szBuffer), TEXT("CLSID\\%s"), szGuid);
  32. if ( pSubKey )
  33. {
  34. StrCatBuff(szBuffer, TEXT("\\"), ARRAYSIZE(szBuffer));
  35. StrCatBuff(szBuffer, pSubKey, ARRAYSIZE(szBuffer));
  36. }
  37. Trace(TEXT("Trying to open -%s-"), szBuffer);
  38. if ( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szBuffer, NULL, KEY_READ, phkey) )
  39. ExitGracefully(hr, E_FAIL, "Failed to open key");
  40. hr = S_OK; // success
  41. exit_gracefully:
  42. TraceLeaveResult(hr);
  43. }
  44. /*-----------------------------------------------------------------------------
  45. / GetRealWindowInfo
  46. / -----------------
  47. / Get the window dimensions and client position.
  48. /
  49. / In:
  50. / hwnd = window to enquire about
  51. / pRect -> receives the client position of the window / == NULL
  52. / pSize -> receives the size of the window / == NULL
  53. /
  54. / Out:
  55. / -
  56. /----------------------------------------------------------------------------*/
  57. EXTERN_C HRESULT GetRealWindowInfo(HWND hwnd, LPRECT pRect, LPSIZE pSize)
  58. {
  59. HRESULT hr;
  60. RECT rect;
  61. TraceEnter(TRACE_COMMON_MISC, "GetRealWindowInfo");
  62. if ( !GetWindowRect(hwnd, &rect) )
  63. ExitGracefully(hr, E_FAIL, "Failed to get window rectangles");
  64. MapWindowPoints(NULL, GetParent(hwnd), (LPPOINT)&rect, 2);
  65. if ( pRect )
  66. *pRect = rect;
  67. if ( pSize )
  68. {
  69. pSize->cx = rect.right - rect.left;
  70. pSize->cy = rect.bottom - rect.top;
  71. }
  72. hr = S_OK;
  73. exit_gracefully:
  74. TraceLeaveResult(hr);
  75. }
  76. /*-----------------------------------------------------------------------------
  77. / OffsetWindow
  78. / ------------
  79. / Adjust the position of the given window by the given delta. If the
  80. / delta is 0,0 then this is a NOP.
  81. /
  82. / In:
  83. / hwnd = window to enquire about
  84. / dx, dy = offset to be applied to the window
  85. /
  86. / Out:
  87. / -
  88. /----------------------------------------------------------------------------*/
  89. EXTERN_C VOID OffsetWindow(HWND hwnd, INT dx, INT dy)
  90. {
  91. RECT rect;
  92. TraceEnter(TRACE_COMMON_MISC, "OffsetWindow");
  93. if ( hwnd && (dx || dy) )
  94. {
  95. GetWindowRect(hwnd, &rect);
  96. MapWindowPoints(NULL, GetParent(hwnd), (LPPOINT)&rect, 2);
  97. SetWindowPos(hwnd, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
  98. }
  99. TraceLeave();
  100. }
  101. /*-----------------------------------------------------------------------------
  102. / CallRegInstall
  103. / --------------
  104. / Call ADVPACK for the given section of our resource based INF>
  105. /
  106. / In:
  107. / hInstance = resource instance to get REGINST section from
  108. / szSection = section name to invoke
  109. /
  110. / Out:
  111. / HRESULT:
  112. /----------------------------------------------------------------------------*/
  113. EXTERN_C HRESULT CallRegInstall(HINSTANCE hInstance, LPSTR szSection)
  114. {
  115. HRESULT hr = E_FAIL;
  116. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  117. TraceEnter(TRACE_COMMON_MISC, "CallRegInstall");
  118. if (hinstAdvPack)
  119. {
  120. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  121. if ( pfnri )
  122. {
  123. STRENTRY seReg[] =
  124. {
  125. // These two NT-specific entries must be at the end
  126. { "25", "%SystemRoot%" },
  127. { "11", "%SystemRoot%\\system32" },
  128. };
  129. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  130. hr = pfnri(hInstance, szSection, &stReg);
  131. }
  132. FreeLibrary(hinstAdvPack);
  133. }
  134. TraceLeaveResult(hr);
  135. }
  136. /*-----------------------------------------------------------------------------
  137. / SetDefButton
  138. / ------------
  139. / Jump through hoops, avoid barking dogs and dice with death all to set
  140. / the default button in a dialog.
  141. /
  142. / In:
  143. / hWnd, idButton = button to set
  144. /
  145. / Out:
  146. / HRESULT:
  147. /----------------------------------------------------------------------------*/
  148. EXTERN_C VOID SetDefButton(HWND hwndDlg, int idButton)
  149. {
  150. LRESULT lr;
  151. LONG style;
  152. TraceEnter(TRACE_COMMON_MISC, "SetDefButton");
  153. if (HIWORD(lr = SendMessage(hwndDlg, DM_GETDEFID, 0, 0)) == DC_HASDEFID)
  154. {
  155. HWND hwndOldDefButton = GetDlgItem(hwndDlg, LOWORD(lr));
  156. style = GetWindowLong(hwndOldDefButton, GWL_STYLE) & ~BS_DEFPUSHBUTTON;
  157. SendMessage (hwndOldDefButton,
  158. BM_SETSTYLE,
  159. MAKEWPARAM(style, 0),
  160. MAKELPARAM(TRUE, 0));
  161. }
  162. SendMessage( hwndDlg, DM_SETDEFID, idButton, 0L );
  163. style = GetWindowLong(GetDlgItem(hwndDlg, idButton), GWL_STYLE)| BS_DEFPUSHBUTTON;
  164. SendMessage( GetDlgItem(hwndDlg, idButton),
  165. BM_SETSTYLE,
  166. MAKEWPARAM( style, 0 ),
  167. MAKELPARAM( TRUE, 0 ));
  168. TraceLeave();
  169. }
  170. /*-----------------------------------------------------------------------------
  171. / Data collection functions
  172. /----------------------------------------------------------------------------*/
  173. /*-----------------------------------------------------------------------------
  174. / AllocStorageMedium
  175. / ------------------
  176. / Allocate a storage medium (validating the clipboard format as required).
  177. /
  178. / In:
  179. / pFmt, pMedium -> describe the allocation
  180. / cbStruct = size of allocation
  181. / ppAlloc -> receives a pointer to the allocation / = NULL
  182. /
  183. / Out:
  184. / HRESULT
  185. /----------------------------------------------------------------------------*/
  186. EXTERN_C HRESULT AllocStorageMedium(FORMATETC* pFmt, STGMEDIUM* pMedium, SIZE_T cbStruct, LPVOID* ppAlloc)
  187. {
  188. HRESULT hr;
  189. TraceEnter(TRACE_COMMON_MISC, "AllocStorageMedium");
  190. TraceAssert(pFmt);
  191. TraceAssert(pMedium);
  192. // Validate parameters
  193. if ( ( cbStruct <= 0 ) || !( pFmt->tymed & TYMED_HGLOBAL ) )
  194. ExitGracefully(hr, E_INVALIDARG, "Zero size stored medium requested or non HGLOBAL");
  195. if ( ( pFmt->ptd ) || !( pFmt->dwAspect & DVASPECT_CONTENT) || !( pFmt->lindex == -1 ) )
  196. ExitGracefully(hr, E_INVALIDARG, "Bad format requested");
  197. // Allocate the medium via GlobalAlloc
  198. pMedium->tymed = TYMED_HGLOBAL;
  199. pMedium->hGlobal = GlobalAlloc(GPTR, cbStruct);
  200. pMedium->pUnkForRelease = NULL;
  201. if ( !pMedium->hGlobal )
  202. ExitGracefully(hr, E_OUTOFMEMORY, "Failed to allocate StgMedium");
  203. hr = S_OK; // success
  204. exit_gracefully:
  205. if ( ppAlloc )
  206. *ppAlloc = SUCCEEDED(hr) ? (LPVOID)pMedium->hGlobal:NULL;
  207. TraceLeaveResult(hr);
  208. }
  209. /*-----------------------------------------------------------------------------
  210. / CopyStorageMedium
  211. / ------------------
  212. / Copies a storage medium (and the data in an HGLOBAL). Only works
  213. / for TYMED_HGLOBAL mediums...
  214. /
  215. / In:
  216. / pMediumDst -> where to copy to...
  217. / pFmt, pMediumSrc -> describe the source
  218. /
  219. / Out:
  220. / HRESULT
  221. /----------------------------------------------------------------------------*/
  222. EXTERN_C HRESULT CopyStorageMedium(FORMATETC* pFmt, STGMEDIUM* pMediumDst, STGMEDIUM* pMediumSrc)
  223. {
  224. HRESULT hr;
  225. LPVOID pSrc, pDst;
  226. HGLOBAL hGlobal;
  227. SIZE_T cbStruct;
  228. TraceEnter(TRACE_COMMON_MISC, "CopyStorageMedium");
  229. if ( !(pFmt->tymed & TYMED_HGLOBAL) )
  230. ExitGracefully(hr, E_INVALIDARG, "Only HGLOBAL mediums suppported to copy");
  231. // stored in a HGLOBAl, therefore get the size, allocate a new storage
  232. // object and copy the data away into it.
  233. cbStruct = GlobalSize((HGLOBAL)pMediumSrc->hGlobal);
  234. hr = AllocStorageMedium(pFmt, pMediumDst, cbStruct, (LPVOID*)&hGlobal);
  235. FailGracefully( hr, "Unable to allocated storage medium" );
  236. *pMediumDst = *pMediumSrc;
  237. pMediumDst->hGlobal = hGlobal;
  238. pSrc = GlobalLock(pMediumSrc->hGlobal);
  239. pDst = GlobalLock(pMediumDst->hGlobal);
  240. CopyMemory(pDst, pSrc, cbStruct);
  241. GlobalUnlock(pMediumSrc->hGlobal);
  242. GlobalUnlock(pMediumDst->hGlobal);
  243. hr = S_OK; // success
  244. exit_gracefully:
  245. TraceLeaveResult(hr);
  246. }
  247. /*-----------------------------------------------------------------------------
  248. / GetStringFromGUID
  249. / -----------------
  250. / Given a GUID convert it to a string.
  251. /
  252. / In:
  253. / rGUID = guid to be converted
  254. / psz, cchMax = buffer to fill
  255. /
  256. / Out:
  257. / NUMBER OF characters
  258. /----------------------------------------------------------------------------*/
  259. static const BYTE c_rgbGuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-', 8, 9, '-', 10, 11, 12, 13, 14, 15 };
  260. static const TCHAR c_szDigits[] = TEXT("0123456789ABCDEF");
  261. EXTERN_C INT GetStringFromGUID(UNALIGNED REFGUID rguid, LPTSTR psz, INT cchMax)
  262. {
  263. INT i;
  264. const BYTE* pBytes = (const BYTE*)&rguid;
  265. if ( cchMax < GUIDSTR_MAX )
  266. return 0;
  267. #ifdef BIG_ENDIAN
  268. // This is the slow, but portable version
  269. wnsprintf(psz, cchMax,
  270. TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  271. rguid->Data1, rguid->Data2, rguid->Data3,
  272. rguid->Data4[0], rguid->Data4[1],
  273. rguid->Data4[2], rguid->Data4[3],
  274. rguid->Data4[4], rguid->Data4[5],
  275. rguid->Data4[6], rguid->Data4[7]);
  276. #else
  277. // The following algorithm is faster than the wsprintf.
  278. *psz++ = TEXT('{');
  279. for (i = 0; i < SIZEOF(c_rgbGuidMap); i++)
  280. {
  281. if (c_rgbGuidMap[i] == TEXT('-')) // don't TEXT() this line
  282. {
  283. *psz++ = TEXT('-');
  284. }
  285. else
  286. {
  287. // Convert a byte-value into a character representation
  288. *psz++ = c_szDigits[ (pBytes[c_rgbGuidMap[i]] & 0xF0) >> 4 ];
  289. *psz++ = c_szDigits[ (pBytes[c_rgbGuidMap[i]] & 0x0F) ];
  290. }
  291. }
  292. *psz++ = TEXT('}');
  293. *psz = TEXT('\0');
  294. #endif /* !BIG_ENDIAN */
  295. return GUIDSTR_MAX;
  296. }
  297. /*-----------------------------------------------------------------------------
  298. / GetGUIDFromString
  299. / -----------------
  300. / Given a string convert it to a GUID.
  301. /
  302. / In:
  303. / psz -> string to be parsed
  304. / rGUID = GUID return into
  305. /
  306. / Out:
  307. / BOOL
  308. /----------------------------------------------------------------------------*/
  309. BOOL _HexStringToDWORD(LPCTSTR * ppsz, DWORD * lpValue, int cDigits, TCHAR chDelim)
  310. {
  311. int ich;
  312. LPCTSTR psz = *ppsz;
  313. DWORD Value = 0;
  314. BOOL fRet = TRUE;
  315. for (ich = 0; ich < cDigits; ich++)
  316. {
  317. TCHAR ch = psz[ich];
  318. if (InRange(ch, TEXT('0'), TEXT('9')))
  319. {
  320. Value = (Value << 4) + ch - TEXT('0');
  321. }
  322. else if ( InRange( (ch |= (TEXT('a')-TEXT('A'))), TEXT('a'), TEXT('f')) )
  323. {
  324. Value = (Value << 4) + ch - TEXT('a') + 10;
  325. }
  326. else
  327. return(FALSE);
  328. }
  329. if (chDelim)
  330. {
  331. fRet = (psz[ich++] == chDelim);
  332. }
  333. *lpValue = Value;
  334. *ppsz = psz+ich;
  335. return fRet;
  336. }
  337. EXTERN_C BOOL GetGUIDFromString(LPCTSTR psz, GUID* pguid)
  338. {
  339. DWORD dw;
  340. if (*psz++ != TEXT('{') /*}*/ )
  341. return FALSE;
  342. if (!_HexStringToDWORD(&psz, &pguid->Data1, SIZEOF(DWORD)*2, TEXT('-')))
  343. return FALSE;
  344. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(WORD)*2, TEXT('-')))
  345. return FALSE;
  346. pguid->Data2 = (WORD)dw;
  347. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(WORD)*2, TEXT('-')))
  348. return FALSE;
  349. pguid->Data3 = (WORD)dw;
  350. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  351. return FALSE;
  352. pguid->Data4[0] = (BYTE)dw;
  353. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, TEXT('-')))
  354. return FALSE;
  355. pguid->Data4[1] = (BYTE)dw;
  356. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  357. return FALSE;
  358. pguid->Data4[2] = (BYTE)dw;
  359. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  360. return FALSE;
  361. pguid->Data4[3] = (BYTE)dw;
  362. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  363. return FALSE;
  364. pguid->Data4[4] = (BYTE)dw;
  365. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  366. return FALSE;
  367. pguid->Data4[5] = (BYTE)dw;
  368. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, 0))
  369. return FALSE;
  370. pguid->Data4[6] = (BYTE)dw;
  371. if (!_HexStringToDWORD(&psz, &dw, SIZEOF(BYTE)*2, /*(*/ TEXT('}')))
  372. return FALSE;
  373. pguid->Data4[7] = (BYTE)dw;
  374. return TRUE;
  375. }