Source code of Windows XP (NT5)
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.

338 lines
9.3 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // StdUtils.cpp
  4. //
  5. // Utilities routines for any snapin.
  6. //
  7. // HISTORY
  8. // t-danmo 96.10.10 Creation.
  9. //
  10. /////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "stdutils.h"
  13. /////////////////////////////////////////////////////////////////////
  14. // CompareMachineNames()
  15. //
  16. // Compare if the strings refer to the same machine (computer).
  17. //
  18. // Return 0 if both strings map to the same machine, otherwise
  19. // return -1 or +1 if machine name differs.
  20. //
  21. // INTERFACE NOTES:
  22. // An empty string means the local machine.
  23. //
  24. // HISTORY
  25. // 02-Jun-97 t-danm Creation.
  26. // 14-Jul-97 t-danm Comment update.
  27. // 29-Jul-97 t-danm Renamed from FCompareMachineNames().
  28. //
  29. int
  30. CompareMachineNames(
  31. LPCTSTR pszMachineName1,
  32. LPCTSTR pszMachineName2)
  33. {
  34. TCHAR szThisMachineName[MAX_COMPUTERNAME_LENGTH + 4];
  35. BOOL fMachine1IsLocal = (pszMachineName1 == NULL || *pszMachineName1 == '\0');
  36. BOOL fMachine2IsLocal = (pszMachineName2 == NULL || *pszMachineName2 == '\0');
  37. if (fMachine1IsLocal)
  38. pszMachineName1 = szThisMachineName;
  39. if (fMachine2IsLocal)
  40. pszMachineName2 = szThisMachineName;
  41. if (pszMachineName1 == pszMachineName2)
  42. return 0;
  43. if (fMachine1IsLocal || fMachine2IsLocal)
  44. {
  45. // Get the computer name
  46. szThisMachineName[0] = _T('\\');
  47. szThisMachineName[1] = _T('\\');
  48. DWORD cchBuffer = MAX_COMPUTERNAME_LENGTH + 1;
  49. VERIFY(::GetComputerName(OUT &szThisMachineName[2], &cchBuffer));
  50. ASSERT(szThisMachineName[2] != _T('\\') && "Machine name has too many backslashes");
  51. }
  52. return lstrcmpi(pszMachineName1, pszMachineName2);
  53. } // CompareMachineNames()
  54. /////////////////////////////////////////////////////////////////////
  55. // HrLoadOleString()
  56. //
  57. // Load a string from the resource and return pointer to allocated
  58. // OLE string.
  59. //
  60. // HISTORY
  61. // 29-Jul-97 t-danm Creation.
  62. //
  63. HRESULT
  64. HrLoadOleString(
  65. UINT uStringId, // IN: String Id to load from the resource
  66. OUT LPOLESTR * ppaszOleString) // OUT: Pointer to pointer to allocated OLE string
  67. {
  68. if (ppaszOleString == NULL)
  69. {
  70. TRACE0("HrLoadOleString() - ppaszOleString is NULL.\n");
  71. return E_POINTER;
  72. }
  73. CString strT; // Temporary string
  74. AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Needed for LoadString()
  75. VERIFY( strT.LoadString(uStringId) );
  76. *ppaszOleString = reinterpret_cast<LPOLESTR>
  77. (CoTaskMemAlloc((strT.GetLength() + 1)* sizeof(wchar_t)));
  78. if (*ppaszOleString == NULL)
  79. return E_OUTOFMEMORY;
  80. USES_CONVERSION;
  81. wcscpy(OUT *ppaszOleString, T2OLE((LPTSTR)(LPCTSTR)strT));
  82. return S_OK;
  83. } // HrLoadOleString()
  84. //
  85. // Nodetype utility routines
  86. // aNodetypeGuids must be defined by the subclass
  87. //
  88. int CheckObjectTypeGUID( const BSTR lpszObjectTypeGUID )
  89. {
  90. ASSERT(NULL != lpszObjectTypeGUID);
  91. for ( int objecttype = 0;
  92. objecttype < g_cNumNodetypeGuids;
  93. objecttype += 1 )
  94. {
  95. if ( !::lstrcmpiW(lpszObjectTypeGUID,g_aNodetypeGuids[objecttype].bstr) )
  96. return objecttype;
  97. }
  98. ASSERT( FALSE );
  99. return 0;
  100. }
  101. int CheckObjectTypeGUID( const GUID* pguid )
  102. {
  103. ASSERT(NULL != pguid);
  104. for ( int objecttype = 0;
  105. objecttype < g_cNumNodetypeGuids;
  106. objecttype += 1 )
  107. {
  108. if ( g_aNodetypeGuids[objecttype].guid == *pguid )
  109. return objecttype;
  110. }
  111. ASSERT( FALSE );
  112. return 0;
  113. }
  114. /////////////////////////////////////////////////////////////////////
  115. // FilemgmtCheckObjectTypeGUID()
  116. //
  117. // Compare the GUID and return the objecttype associated with
  118. // the guid.
  119. // If no match found, return -1.
  120. //
  121. // HISTORY
  122. // 14-Jul-97 t-danm Creation. Inspired from CheckObjectTypeGUID()
  123. // but does not assert if the GUID is not found.
  124. //
  125. int FilemgmtCheckObjectTypeGUID(const GUID* pguid )
  126. {
  127. ASSERT(NULL != pguid);
  128. for ( int objecttype = 0;
  129. objecttype < g_cNumNodetypeGuids;
  130. objecttype += 1 )
  131. {
  132. if ( g_aNodetypeGuids[objecttype].guid == *pguid )
  133. return objecttype;
  134. }
  135. return -1;
  136. } // FilemgmtCheckObjectTypeGUID()
  137. const BSTR GetObjectTypeString( int objecttype )
  138. {
  139. if (objecttype < 0 || objecttype >= g_cNumNodetypeGuids)
  140. {
  141. ASSERT( FALSE );
  142. objecttype = 0;
  143. }
  144. return g_aNodetypeGuids[objecttype].bstr;
  145. }
  146. const GUID* GetObjectTypeGUID( int objecttype )
  147. {
  148. if (objecttype < 0 || objecttype >= g_cNumNodetypeGuids)
  149. {
  150. ASSERT( FALSE );
  151. objecttype = 0;
  152. }
  153. return &(g_aNodetypeGuids[objecttype].guid);
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Function: SynchronousCreateProcess
  158. //
  159. // Synopsis: Invoke a separate UI process as a modal window.
  160. //
  161. //----------------------------------------------------------------------------
  162. HRESULT SynchronousCreateProcess(
  163. HWND hWnd,
  164. LPCTSTR pszAppName,
  165. LPCTSTR pszCommandLine,
  166. LPDWORD lpdwExitCode
  167. )
  168. {
  169. HRESULT hr = S_OK;
  170. BOOL bReturn = FALSE;
  171. STARTUPINFO si;
  172. PROCESS_INFORMATION pi;
  173. //
  174. // disable the MMC main frame window to prevent it from
  175. // being shut down. The process we're going to create must
  176. // display a UI, such that, it behaves like a modal window.
  177. //
  178. ::EnableWindow(hWnd, FALSE);
  179. *lpdwExitCode = 0;
  180. ZeroMemory(&si, sizeof(STARTUPINFO));
  181. si.cb = sizeof(STARTUPINFO);
  182. bReturn = CreateProcess(
  183. pszAppName, //LPCTSTR lpApplicationName
  184. const_cast<LPTSTR>(pszCommandLine), //LPTSTR lpCommandLine
  185. NULL, //LPSECURITY_ATTRIBUTES lpProcessAttributes
  186. NULL, //LPSECURITY_ATTRIBUTES lpThreadAttributes
  187. FALSE, //BOOL bInheritHandles
  188. NORMAL_PRIORITY_CLASS, //DWORD dwCreationFlags
  189. NULL, //LPVOID lpEnvironment
  190. NULL, //lpCurrentDirectory
  191. &si, //LPSTARTUPINFO lpStartupInfo
  192. &pi //LPPROCESS_INFORMATION lpProcessInformation
  193. );
  194. if (!bReturn)
  195. {
  196. hr = HRESULT_FROM_WIN32(GetLastError());
  197. } else
  198. {
  199. //
  200. // while process is still running, pump message to MMC main window,
  201. // such that it will repaint itself
  202. //
  203. while (TRUE)
  204. {
  205. MSG tempMSG;
  206. DWORD dwWait;
  207. while(::PeekMessage(&tempMSG,NULL, 0, 0, PM_REMOVE))
  208. DispatchMessage(&tempMSG);
  209. dwWait = MsgWaitForMultipleObjects(1, &(pi.hProcess), FALSE, INFINITE, QS_ALLINPUT);
  210. if ( 0 == (dwWait - WAIT_OBJECT_0))
  211. break; // process is done
  212. };
  213. bReturn = GetExitCodeProcess(pi.hProcess, lpdwExitCode);
  214. if (!bReturn)
  215. hr = HRESULT_FROM_WIN32(GetLastError());
  216. CloseHandle(pi.hThread);
  217. CloseHandle(pi.hProcess);
  218. }
  219. //
  220. // enable MMC main frame window before return
  221. //
  222. ::EnableWindow(hWnd, TRUE);
  223. return hr;
  224. }
  225. /*
  226. This code is not working yet. The problem is that it hangs the
  227. message loop, preventing redraw. One possible approach is to disable the
  228. top-level window and spin off a thread which waits for the process to stop,
  229. then the thread reenables the top-level window and calls UpdateAllViews.
  230. DWORD WINAPI ProcessMonitor(LPVOID pv)
  231. {
  232. }
  233. class CSyncThread : public CThread
  234. {
  235. };
  236. HRESULT SynchronousCreateProcess(LPCTSTR cpszCommandLine,
  237. SynchronousProcessCompletionRoutine pfunc,
  238. PVOID pvFuncParams)
  239. // does not handle completion routine
  240. {
  241. PROCESS_INFORMATION piProcInfo;
  242. (void) ::memset(&piProcInfo,0,sizeof(piProcInfo));
  243. STARTUPINFO si;
  244. (void) ::memset(&si,0,sizeof(si));
  245. ::GetStartupInfo( &si );
  246. //
  247. // MarkL 1/30/97: Is pszCommandLine a static string?
  248. // It can not be read only. It is modified temporarily by the call
  249. // if you do not specify lpszImageName. There is no query to see
  250. // if a process is running. You can test to see if it has exited
  251. // using waitforsingleobject to see if the process object is signaled.
  252. //
  253. // MarkL also confirms that the handle should absolutely always
  254. // be signalled when the process dies.
  255. //
  256. LPTSTR pszCommandLine = (LPTSTR)
  257. ::alloca(sizeof(TCHAR)*(::_tcslen(cpszCommandLine)+1));
  258. ::_tcscpy(pszCommandLine,cpszCommandLine);
  259. if ( !::CreateProcess(
  260. NULL, // LPCTSTR lpszImageName
  261. pszCommandLine, // LPTSTR lpszCommandLine
  262. NULL, // LPSECURITY_ATTRIBUTES lpsaProcess
  263. NULL, // LPSECURITY_ATTRIBUTES lpsaThread
  264. FALSE, // BOOL fInheritHandles
  265. 0L, // DWORD fdwCreate
  266. NULL, // LPVOID lpvEnvironment
  267. NULL, // LPTSTR lpszCurDir
  268. &si, // LPSTARTUPINFO lpsiStartInfo
  269. &piProcInfo // LPPROCESS_INFORMATION lppiProcInfo
  270. ) )
  271. {
  272. DWORD dwErr = ::GetLastError();
  273. ASSERT( ERROR_SUCCESS != dwErr );
  274. return HRESULT_FROM_WIN32(dwErr);
  275. }
  276. ASSERT( NULL != piProcInfo.hProcess );
  277. VERIFY( WAIT_OBJECT_0 ==
  278. ::WaitForSingleObject( piProcInfo.hProcess, INFINITE ) );
  279. VERIFY( ::CloseHandle( piProcInfo.hProcess ) );
  280. VERIFY( ::CloseHandle( piProcInfo.hThread ) );
  281. return S_OK;
  282. }
  283. */
  284. LPOLESTR CoTaskAllocString( LPCOLESTR psz )
  285. {
  286. if (NULL == psz)
  287. return NULL;
  288. LPOLESTR pszReturn = (LPOLESTR)CoTaskMemAlloc( (lstrlen(psz)+1)*sizeof(OLECHAR) );
  289. if (NULL != pszReturn)
  290. lstrcpy( pszReturn, psz );
  291. ASSERT( NULL != pszReturn );
  292. return pszReturn;
  293. }
  294. LPOLESTR CoTaskLoadString( UINT nResourceID )
  295. {
  296. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  297. // load the resource
  298. CString strText;
  299. strText.LoadString( nResourceID );
  300. ASSERT( !strText.IsEmpty() );
  301. return CoTaskAllocString( const_cast<BSTR>((LPCTSTR)strText) );
  302. }