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.

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