misc.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 14k
Category:

Windows Kernel

Development Platform:

Visual C++

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