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.

282 lines
7.8 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // File: setupenum.cpp
  6. //
  7. // The current order of enumeration is whatever order we read from the registry
  8. //
  9. // History:
  10. // 6-11-98 by toddb
  11. //------------------------------------------------------------------------
  12. #include "priv.h"
  13. // Do not build this file if on Win9X or NT4
  14. #ifndef DOWNLEVEL_PLATFORM
  15. #include <shellp.h> // for IsUserAnAdmin
  16. #include "setupenum.h"
  17. #include "appwizid.h"
  18. #define c_szOCSetupKey TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Setup\\OCManager\\ToDoList")
  19. //-----------------------------------------------------------------------
  20. // OCSetupApp
  21. //-----------------------------------------------------------------------
  22. COCSetupApp::COCSetupApp()
  23. {
  24. // This must be heap alloced so everything should be zero'ed out.
  25. // Make sure this wasn't stack alloced using these asserts:
  26. ASSERT(0 == _szDisplayName[0]);
  27. ASSERT(0 == _szApp[0]);
  28. ASSERT(0 == _szArgs[0]);
  29. }
  30. COCSetupApp::~COCSetupApp()
  31. {
  32. }
  33. //-----------------------------------------------------------------------
  34. // GetAppInfo
  35. //
  36. // Fills in the only valid field in our psuedo APPINFODATA structure.
  37. BOOL COCSetupApp::GetAppInfo(PAPPINFODATA pai)
  38. {
  39. if (pai->cbSize != SIZEOF(APPINFODATA))
  40. return FALSE;
  41. DWORD dwInfoFlags = pai->dwMask;
  42. pai->dwMask = 0;
  43. if (dwInfoFlags & AIM_DISPLAYNAME)
  44. {
  45. if (SUCCEEDED(SHStrDup(_szDisplayName, &pai->pszDisplayName)))
  46. pai->dwMask |= AIM_DISPLAYNAME;
  47. }
  48. return TRUE;
  49. }
  50. //-----------------------------------------------------------------------
  51. // ReadFromKey
  52. //
  53. // This function reads the actual data from the given reg key. It returns
  54. // TRUE if all required fields contained string data.
  55. BOOL COCSetupApp::ReadFromKey( HKEY hkey )
  56. {
  57. DWORD dwType;
  58. DWORD dwSize;
  59. dwSize = sizeof(_szDisplayName);
  60. if ( ERROR_SUCCESS != RegQueryValueEx( hkey, TEXT("Title"), 0, &dwType, (LPBYTE)_szDisplayName, &dwSize ) ||
  61. dwType != REG_SZ )
  62. {
  63. // DisplayName is required
  64. return FALSE;
  65. }
  66. dwSize = sizeof(_szApp);
  67. if ( ERROR_SUCCESS == RegQueryValueEx( hkey, TEXT("ConfigCommand"), 0, &dwType, (LPBYTE)_szApp, &dwSize ) &&
  68. (dwType == REG_SZ || dwType == REG_EXPAND_SZ) )
  69. {
  70. if ( dwType == REG_EXPAND_SZ )
  71. {
  72. TCHAR szBuf[MAX_PATH];
  73. ExpandEnvironmentStrings(_szApp, szBuf, ARRAYSIZE(szBuf));
  74. lstrcpyn(_szApp, szBuf, ARRAYSIZE(_szApp));
  75. }
  76. }
  77. else
  78. {
  79. // ConfigCommand is required
  80. return FALSE;
  81. }
  82. dwSize = sizeof(_szArgs);
  83. if ( ERROR_SUCCESS == RegQueryValueEx( hkey, TEXT("ConfigArgs"), 0, &dwType, (LPBYTE)_szArgs, &dwSize ) &&
  84. (dwType == REG_SZ || dwType == REG_EXPAND_SZ) )
  85. {
  86. if ( dwType == REG_EXPAND_SZ )
  87. {
  88. TCHAR szBuf[MAX_PATH];
  89. ExpandEnvironmentStrings(_szArgs, szBuf, ARRAYSIZE(szBuf));
  90. lstrcpyn(_szArgs, szBuf, ARRAYSIZE(_szArgs));
  91. }
  92. }
  93. else
  94. {
  95. // This is optional so we don't fail. Instead simply insure that _szArgs is an empty string.
  96. _szArgs[0] = 0;
  97. }
  98. return TRUE;
  99. }
  100. BOOL COCSetupApp::Run()
  101. {
  102. // REARCHITECT: (stephstm, 03/17/99) we should probably wait on a job object in case
  103. // the spawned process spawns some other process(es) and then exits before them.
  104. BOOL fRet = FALSE;
  105. SHELLEXECUTEINFO sei = {0};
  106. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  107. sei.fMask = SEE_MASK_NOCLOSEPROCESS;
  108. sei.hwnd = GetDesktopWindow();
  109. sei.lpFile = _szApp;
  110. sei.lpParameters = _szArgs[0] ? _szArgs : NULL;
  111. sei.nShow = SW_SHOWDEFAULT;
  112. fRet = ShellExecuteEx(&sei);
  113. if (fRet)
  114. {
  115. DWORD dwRet;
  116. do
  117. {
  118. MSG msg;
  119. // Get and process the messages!
  120. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  121. {
  122. TranslateMessage(&msg);
  123. DispatchMessage(&msg);
  124. }
  125. // MsgWaitForMultipleObjects can fail with -1 being returned!
  126. dwRet = MsgWaitForMultipleObjects(1, &sei.hProcess, FALSE, INFINITE, QS_ALLINPUT);
  127. }
  128. while ((WAIT_OBJECT_0 != dwRet) && (-1 != dwRet));
  129. // Did MsgWait... failed?
  130. if (-1 == dwRet)
  131. {
  132. // Yes, kill the process
  133. TerminateProcess(sei.hProcess, 0);
  134. fRet = FALSE;
  135. }
  136. CloseHandle(sei.hProcess);
  137. }
  138. else
  139. {
  140. ShellMessageBox(HINST_THISDLL, sei.hwnd, MAKEINTRESOURCE( IDS_CONFIGURE_FAILED ),
  141. MAKEINTRESOURCE( IDS_NAME ),
  142. MB_OK | MB_ICONEXCLAMATION);
  143. }
  144. return fRet;
  145. }
  146. //-----------------------------------------------------------------------
  147. // OCSetupEnum
  148. //-----------------------------------------------------------------------
  149. COCSetupEnum::COCSetupEnum()
  150. {
  151. _hkeyRoot = 0;
  152. _iRegEnumIndex = -1;
  153. }
  154. COCSetupEnum::~COCSetupEnum()
  155. {
  156. if ( _hkeyRoot )
  157. {
  158. RegCloseKey( _hkeyRoot );
  159. }
  160. }
  161. //-----------------------------------------------------------------------
  162. // s_OCSetupNeeded
  163. //
  164. // This checks for the neccessaary conditions to display the OC Setup portion of the ARP.
  165. // This section is only shown if the current user is a member of the administrators group
  166. // AND there are any items listed in the registry that need to be displayed.
  167. BOOL COCSetupEnum::s_OCSetupNeeded()
  168. {
  169. BOOL fResult = FALSE;
  170. HKEY hkey;
  171. // Temporarily open the reg key to see if it exists and has any sub keys
  172. if ( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szOCSetupKey, 0, KEY_READ, &hkey ) )
  173. {
  174. TCHAR szBuf[MAX_PATH];
  175. if ( ERROR_SUCCESS == RegEnumKey( hkey, 0, szBuf, ARRAYSIZE(szBuf) ) )
  176. {
  177. // Yes, there are OCSetup items, but is the current user an administrator?
  178. if ( IsUserAnAdmin() )
  179. {
  180. fResult = TRUE;
  181. }
  182. }
  183. RegCloseKey( hkey );
  184. }
  185. return fResult;
  186. }
  187. //-----------------------------------------------------------------------
  188. // EnumOCSetupItems
  189. //
  190. // This begins the enumeration by opening the required registry key. This does
  191. // not attempt to read any of the sub items so there is no garentee that the
  192. // first call to Next() will succeed.
  193. BOOL COCSetupEnum::EnumOCSetupItems()
  194. {
  195. ASSERT( NULL == _hkeyRoot );
  196. // Open the reg key, return true if it's open. We leave the key open until
  197. // our destructor is called since we need this key to do the enumeration.
  198. if ( ERROR_SUCCESS == RegOpenKeyEx(
  199. HKEY_LOCAL_MACHINE,
  200. c_szOCSetupKey,
  201. 0,
  202. KEY_READ,
  203. &_hkeyRoot ) )
  204. {
  205. return TRUE;
  206. }
  207. return FALSE;
  208. }
  209. //-----------------------------------------------------------------------
  210. // Next
  211. //
  212. // Reads the data from the next sub key of _hkeyRoot and returns the data in the
  213. // out pointer. Returns TRUE if the out pointer is a valid COCSetupApp object.
  214. BOOL COCSetupEnum::Next(COCSetupApp **ppocsa)
  215. {
  216. HKEY hkeySub;
  217. TCHAR szSubKeyName[MAX_PATH];
  218. // We open each subkey of the root key and attempt to read an OCSetup item from the subkey.
  219. if ( ERROR_SUCCESS == RegEnumKey( _hkeyRoot, ++_iRegEnumIndex, szSubKeyName, ARRAYSIZE(szSubKeyName) ) )
  220. {
  221. if ( ERROR_SUCCESS == RegOpenKeyEx( _hkeyRoot, szSubKeyName, 0, KEY_READ, &hkeySub ) )
  222. {
  223. *ppocsa = new COCSetupApp();
  224. if ( *ppocsa )
  225. {
  226. if ( (*ppocsa)->ReadFromKey( hkeySub ) )
  227. {
  228. RegCloseKey( hkeySub );
  229. return TRUE;
  230. }
  231. delete *ppocsa;
  232. }
  233. RegCloseKey( hkeySub );
  234. }
  235. // fall through
  236. }
  237. *ppocsa = NULL;
  238. return FALSE;
  239. }
  240. #endif //DOWNLEVEL_PLATFORM