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.

685 lines
17 KiB

  1. #include "gptext.h"
  2. #include <initguid.h>
  3. #include <iadsp.h>
  4. extern "C"{
  5. #include "wlrsop.h"
  6. }
  7. #include "wirelessext.h"
  8. #include "SmartPtr.h"
  9. #include "wbemtime.h"
  10. #include "xpsp1res.h"
  11. #define GPEXT_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{0ACDD40C-75AC-47ab-BAA0-BF6DE7E7FE63}")
  12. #define POLICY_PATH TEXT("Software\\Policies\\Microsoft\\Windows\\Wireless\\GPTWirelessPolicy")
  13. LPWSTR GetWirelessAttributes[] = {L"msieee80211-ID", L"cn", L"description"};
  14. HINSTANCE
  15. WirelessGetSPResModule()
  16. {
  17. static HINSTANCE st_hModule = NULL;
  18. if (st_hModule == NULL)
  19. {
  20. WCHAR wszFullPath[_MAX_PATH];
  21. if (ExpandEnvironmentStrings(
  22. L"%systemroot%\\system32\\xpsp1res.dll",
  23. wszFullPath,
  24. _MAX_PATH) != 0)
  25. {
  26. st_hModule = LoadLibraryEx(
  27. wszFullPath,
  28. NULL,
  29. 0);
  30. }
  31. }
  32. return st_hModule;
  33. }
  34. HRESULT
  35. RegisterWireless(void)
  36. {
  37. HKEY hKey;
  38. LONG lResult;
  39. DWORD dwDisp, dwValue;
  40. TCHAR szBuffer[512];
  41. szBuffer[0]=L'\0';
  42. lResult = RegCreateKeyEx (
  43. HKEY_LOCAL_MACHINE,
  44. GPEXT_PATH,
  45. 0,
  46. NULL,
  47. REG_OPTION_NON_VOLATILE,
  48. KEY_WRITE,
  49. NULL,
  50. &hKey,
  51. &dwDisp
  52. );
  53. if (lResult != ERROR_SUCCESS)
  54. {
  55. return lResult;
  56. }
  57. LoadString(WirelessGetSPResModule(), IDS_PEAP_WIRELESS, szBuffer, ARRAYSIZE(szBuffer));
  58. RegSetValueEx (
  59. hKey,
  60. NULL,
  61. 0,
  62. REG_SZ,
  63. (LPBYTE)szBuffer,
  64. (lstrlen(szBuffer) + 1) * sizeof(TCHAR)
  65. );
  66. RegSetValueEx (
  67. hKey,
  68. TEXT("ProcessGroupPolicy"),
  69. 0,
  70. REG_SZ,
  71. (LPBYTE)TEXT("ProcessWIRELESSPolicy"),
  72. (lstrlen(TEXT("ProcessWIRELESSPolicy")) + 1) * sizeof(TCHAR)
  73. );
  74. szBuffer[0] = L'\0';
  75. wcscpy(szBuffer, L"gptext.dll");
  76. RegSetValueEx (
  77. hKey,
  78. TEXT("DllName"),
  79. 0,
  80. REG_EXPAND_SZ,
  81. (LPBYTE)szBuffer,
  82. (lstrlen(szBuffer) + 1) * sizeof(TCHAR)
  83. );
  84. dwValue = 1;
  85. RegSetValueEx (
  86. hKey,
  87. TEXT("NoUserPolicy"),
  88. 0,
  89. REG_DWORD,
  90. (LPBYTE)&dwValue,
  91. sizeof(dwValue));
  92. RegSetValueEx (
  93. hKey,
  94. TEXT("NoGPOListChanges"),
  95. 0,
  96. REG_DWORD,
  97. (LPBYTE)&dwValue,
  98. sizeof(dwValue));
  99. RegCloseKey (hKey);
  100. return S_OK;
  101. }
  102. HRESULT
  103. UnregisterWireless(void)
  104. {
  105. DWORD dwError = 0;
  106. dwError = RegDeleteKey (HKEY_LOCAL_MACHINE, GPEXT_PATH);
  107. return HRESULT_FROM_WIN32(dwError);
  108. }
  109. DWORD
  110. ProcessWIRELESSPolicy(
  111. DWORD dwFlags, // GPO_INFO_FLAGS
  112. HANDLE hToken, // User or machine token
  113. HKEY hKeyRoot, // Root of registry
  114. PGROUP_POLICY_OBJECT pDeletedGPOList, // Linked list of deleted GPOs
  115. PGROUP_POLICY_OBJECT pChangedGPOList, // Linked list of changed GPOs
  116. ASYNCCOMPLETIONHANDLE pHandle, // For asynchronous completion
  117. BOOL *pbAbort, // If true, then abort GPO processing
  118. PFNSTATUSMESSAGECALLBACK pStatusCallback // Callback function for displaying status messages
  119. )
  120. {
  121. // Call ProcessWIRELESSPolicy & get path -> polstore funcs
  122. LPWSTR pszWIRELESSPolicyPath = NULL;
  123. WCHAR szWIRELESSPolicyName[MAX_PATH]; //policy name
  124. WCHAR szWIRELESSPolicyDescription[512]; //policy descr
  125. WCHAR szWIRELESSPolicyID[512]; //policy descr
  126. HRESULT hr = S_OK;
  127. PGROUP_POLICY_OBJECT pGPO = NULL;
  128. GPO_INFO GPOInfo;
  129. //
  130. // Call CoInitialize for all the COM work we're doing
  131. //
  132. hr = CoInitializeEx(NULL,0);
  133. if (FAILED(hr)) {
  134. goto error;
  135. }
  136. memset(szWIRELESSPolicyName, 0, sizeof(WCHAR)*MAX_PATH);
  137. memset(szWIRELESSPolicyDescription, 0, sizeof(WCHAR)*512);
  138. memset(szWIRELESSPolicyID, 0, sizeof(WCHAR)*512);
  139. // First process the Deleted GPO List. If there is a single
  140. // entry on the GPO list, just delete the entire list.
  141. // Example Rex->Cassius->Brutus. If the delete List has
  142. // Cassius to be deleted, then really, we shouldn't be deleting
  143. // our registry entry because we're interested in Brutus which
  144. // has not be deleted. But in our case, the pChangedGPOList will
  145. // have all the information, so Brutus gets written back in the
  146. // next stage.
  147. //
  148. if (pDeletedGPOList) {
  149. DeleteWirelessPolicyFromRegistry();
  150. }
  151. if(pChangedGPOList) {
  152. DWORD dwNumGPO = 0;
  153. for(pGPO = pChangedGPOList; pGPO; pGPO = pGPO->pNext) {
  154. dwNumGPO++;
  155. //
  156. // Write only the last, highest precedence policy to registry
  157. //
  158. if(pGPO->pNext == NULL) {
  159. hr = RetrieveWirelessPolicyFromDS(
  160. pGPO,
  161. &pszWIRELESSPolicyPath,
  162. szWIRELESSPolicyName,
  163. szWIRELESSPolicyDescription,
  164. szWIRELESSPolicyID
  165. );
  166. if (FAILED(hr)) {
  167. goto error;
  168. }
  169. hr = WriteWirelessPolicyToRegistry(
  170. pszWIRELESSPolicyPath,
  171. szWIRELESSPolicyName,
  172. szWIRELESSPolicyDescription,
  173. szWIRELESSPolicyID
  174. );
  175. if (pszWIRELESSPolicyPath) {
  176. LocalFree(pszWIRELESSPolicyPath);
  177. pszWIRELESSPolicyPath = NULL;
  178. }
  179. if (FAILED(hr)) {
  180. goto error; // WMI store still consistent
  181. }
  182. }
  183. }
  184. DebugMsg( (DM_WARNING, L"wirelessext::ProcessWIRELESSPolicyEx: dwNumGPO: %d", dwNumGPO) );
  185. }
  186. DebugMsg( (DM_WARNING, L"wirelessext::ProcessWIRELESSPolicyEx completed") );
  187. PingWirelessPolicyAgent();
  188. CoUninitialize();
  189. return(ERROR_SUCCESS);
  190. error:
  191. /* Cannot Result in a double delete becuase,
  192. whenever we free, we set the pszWirelessPolicyPath to NULL
  193. so that freeing happens only once
  194. */
  195. if (pszWIRELESSPolicyPath) {
  196. LocalFree(pszWIRELESSPolicyPath);
  197. pszWIRELESSPolicyPath = NULL;
  198. }
  199. return(ERROR_POLICY_OBJECT_NOT_FOUND);
  200. }
  201. HRESULT
  202. CreateWirelessChildPath(
  203. LPWSTR pszParentPath,
  204. LPWSTR pszChildComponent,
  205. BSTR * ppszChildPath
  206. )
  207. {
  208. HRESULT hr = S_OK;
  209. IADsPathname *pPathname = NULL;
  210. hr = CoCreateInstance(
  211. CLSID_Pathname,
  212. NULL,
  213. CLSCTX_ALL,
  214. IID_IADsPathname,
  215. (void**)&pPathname
  216. );
  217. BAIL_ON_FAILURE(hr);
  218. hr = pPathname->Set(pszParentPath, ADS_SETTYPE_FULL);
  219. BAIL_ON_FAILURE(hr);
  220. hr = pPathname->AddLeafElement(pszChildComponent);
  221. BAIL_ON_FAILURE(hr);
  222. hr = pPathname->Retrieve(ADS_FORMAT_X500, ppszChildPath);
  223. BAIL_ON_FAILURE(hr);
  224. error:
  225. if (pPathname) {
  226. pPathname->Release();
  227. }
  228. return(hr);
  229. }
  230. HRESULT
  231. RetrieveWirelessPolicyFromDS(
  232. PGROUP_POLICY_OBJECT pGPOInfo,
  233. LPWSTR *ppszWirelessPolicyPath,
  234. LPWSTR pszWirelessPolicyName,
  235. LPWSTR pszWirelessPolicyDescription,
  236. LPWSTR pszWirelessPolicyID
  237. )
  238. {
  239. LPWSTR pszMachinePath = NULL;
  240. BSTR pszMicrosoftPath = NULL;
  241. BSTR pszWindowsPath = NULL;
  242. BSTR pszWirelessPath = NULL;
  243. BSTR pszLocWirelessPolicy = NULL;
  244. IDirectoryObject * pDirectoryObject = NULL;
  245. IDirectoryObject * pWirelessObject = NULL;
  246. IDirectorySearch * pWirelessSearch = NULL;
  247. BOOL bFound = FALSE;
  248. ADS_SEARCH_HANDLE hSearch;
  249. ADS_SEARCH_COLUMN col;
  250. WCHAR pszLocName[MAX_PATH+10]; // We need to store only CN=, in additon to the name.
  251. LPWSTR pszWirelessPolicyPath = NULL;
  252. DWORD dwWirelessPolicyPathLen = 0;
  253. DWORD dwError = 0;
  254. LPWSTR pszOwnersReference = L"wifiOwnersReference";
  255. HRESULT hr = S_OK;
  256. PADS_ATTR_INFO pAttributeEntries = NULL;
  257. DWORD dwNumAttributesReturned = 0;
  258. DWORD i = 0;
  259. PADS_ATTR_INFO pAttributeEntry = NULL;
  260. pszMachinePath = pGPOInfo->lpDSPath;
  261. // Build the fully qualified ADsPath for my object
  262. hr = CreateWirelessChildPath(
  263. pszMachinePath,
  264. L"cn=Microsoft",
  265. &pszMicrosoftPath
  266. );
  267. BAIL_ON_FAILURE(hr);
  268. hr = CreateWirelessChildPath(
  269. pszMicrosoftPath,
  270. L"cn=Windows",
  271. &pszWindowsPath
  272. );
  273. BAIL_ON_FAILURE(hr);
  274. hr = CreateWirelessChildPath(
  275. pszWindowsPath,
  276. L"cn=Wireless",
  277. &pszWirelessPath
  278. );
  279. BAIL_ON_FAILURE(hr);
  280. hr = ADsOpenObject(
  281. pszWirelessPath,
  282. NULL,
  283. NULL,
  284. ADS_SECURE_AUTHENTICATION | ADS_USE_SEALING | ADS_USE_SIGNING,
  285. IID_IDirectorySearch,
  286. (void **)&pWirelessSearch
  287. );
  288. BAIL_ON_FAILURE(hr);
  289. hr = pWirelessSearch->ExecuteSearch(
  290. L"(&(objectClass=msieee80211-Policy))", GetWirelessAttributes, 3, &hSearch );
  291. if (!SUCCEEDED(hr)) {
  292. pWirelessSearch->CloseSearchHandle(hSearch);
  293. BAIL_ON_FAILURE(hr);
  294. }
  295. hr = pWirelessSearch->GetNextRow(hSearch);
  296. if (!SUCCEEDED(hr)) {
  297. pWirelessSearch->CloseSearchHandle(hSearch);
  298. BAIL_ON_FAILURE(hr);
  299. }
  300. hr = pWirelessSearch->GetColumn(hSearch, L"cn", &col);
  301. if (!SUCCEEDED(hr)) {
  302. pWirelessSearch->CloseSearchHandle(hSearch);
  303. BAIL_ON_FAILURE(hr);
  304. }
  305. if (col.dwADsType != ADSTYPE_CASE_IGNORE_STRING) {
  306. DebugMsg((DM_ASSERT, L"wirelessext::RetrievePolicyFromDS: cn NOT adstype_case_ignore_string"));
  307. pWirelessSearch->FreeColumn(&col);
  308. pWirelessSearch->CloseSearchHandle(hSearch);
  309. hr = E_ADS_BAD_PARAMETER;
  310. BAIL_ON_FAILURE(hr);
  311. }
  312. wcscpy(pszWirelessPolicyName, col.pADsValues->CaseIgnoreString);
  313. pWirelessSearch->FreeColumn(&col);
  314. pWirelessSearch->CloseSearchHandle(hSearch);
  315. wcscpy(pszLocName, L"\0");
  316. wcscpy(pszLocName,L"CN=");
  317. wcscat(pszLocName,pszWirelessPolicyName);
  318. hr = CreateWirelessChildPath(
  319. pszWirelessPath,
  320. pszLocName,
  321. &pszLocWirelessPolicy
  322. );
  323. BAIL_ON_FAILURE(hr);
  324. hr = ADsOpenObject(
  325. pszLocWirelessPolicy,
  326. NULL,
  327. NULL,
  328. ADS_SECURE_AUTHENTICATION | ADS_USE_SEALING | ADS_USE_SIGNING,
  329. IID_IDirectoryObject,
  330. (void **)&pWirelessObject
  331. );
  332. BAIL_ON_FAILURE(hr);
  333. hr = pWirelessObject->GetObjectAttributes(
  334. GetWirelessAttributes,
  335. 3,
  336. &pAttributeEntries,
  337. &dwNumAttributesReturned
  338. );
  339. BAIL_ON_FAILURE(hr);
  340. if (dwNumAttributesReturned == 0) {
  341. hr = E_FAIL;
  342. BAIL_ON_FAILURE(hr);
  343. }
  344. //
  345. // Process the PathName
  346. //
  347. //
  348. // Process the ID
  349. //
  350. for (i = 0; i < dwNumAttributesReturned; i++) {
  351. pAttributeEntry = pAttributeEntries + i;
  352. if (!_wcsicmp(pAttributeEntry->pszAttrName, L"msieee80211-ID")) {
  353. wcscpy(pszWirelessPolicyID, pAttributeEntry->pADsValues->DNString);
  354. bFound = TRUE;
  355. break;
  356. }
  357. }
  358. if (!bFound) {
  359. hr = E_FAIL;
  360. BAIL_ON_FAILURE(hr);
  361. }
  362. //
  363. // Process the description
  364. //
  365. wcscpy(pszWirelessPolicyDescription,L"\0");
  366. for (i = 0; i < dwNumAttributesReturned; i++) {
  367. pAttributeEntry = pAttributeEntries + i;
  368. if (!_wcsicmp(pAttributeEntry->pszAttrName, L"description")) {
  369. wcscpy(pszWirelessPolicyDescription, pAttributeEntry->pADsValues->DNString);
  370. break;
  371. }
  372. }
  373. dwWirelessPolicyPathLen = wcslen(pszLocWirelessPolicy);
  374. pszWirelessPolicyPath = (LPWSTR) LocalAlloc(
  375. LPTR,
  376. sizeof(WCHAR) * (dwWirelessPolicyPathLen+1)
  377. );
  378. if (!pszWirelessPolicyPath) {
  379. dwError = GetLastError();
  380. hr = HRESULT_FROM_WIN32(dwError);
  381. }
  382. BAIL_ON_FAILURE(hr);
  383. memset(pszWirelessPolicyPath, 0, sizeof(WCHAR) * (dwWirelessPolicyPathLen+1));
  384. wcscpy(pszWirelessPolicyPath, pszLocWirelessPolicy);
  385. *ppszWirelessPolicyPath = pszWirelessPolicyPath;
  386. error:
  387. if (pszLocWirelessPolicy) {
  388. SysFreeString(pszLocWirelessPolicy);
  389. }
  390. if (pszWirelessPath) {
  391. SysFreeString(pszWirelessPath);
  392. }
  393. if (pszWindowsPath) {
  394. SysFreeString(pszWindowsPath);
  395. }
  396. if (pszMicrosoftPath) {
  397. SysFreeString(pszMicrosoftPath);
  398. }
  399. return(hr);
  400. }
  401. DWORD
  402. DeleteWirelessPolicyFromRegistry(
  403. )
  404. {
  405. DWORD dwError = 0;
  406. HKEY hKey = NULL;
  407. DWORD dwDisp = 0;
  408. dwError = RegCreateKeyEx (
  409. HKEY_LOCAL_MACHINE,
  410. TEXT("Software\\Policies\\Microsoft\\Windows\\Wireless"),
  411. 0,
  412. NULL,
  413. REG_OPTION_NON_VOLATILE,
  414. KEY_ALL_ACCESS,
  415. NULL,
  416. &hKey,
  417. &dwDisp
  418. );
  419. if (dwError) {
  420. goto error;
  421. }
  422. dwError = RegDeleteKey(
  423. hKey,
  424. L"GPTWirelessPolicy"
  425. );
  426. /*
  427. dwError = RegDeleteValue(
  428. hKey,
  429. TEXT("DSWIRELESSPolicyPath")
  430. );
  431. dwError = RegDeleteValue(
  432. hKey,
  433. TEXT("DSWIRELESSPolicyName")
  434. );*/
  435. error:
  436. if (hKey) {
  437. RegCloseKey (hKey);
  438. }
  439. return(dwError);
  440. }
  441. DWORD
  442. WriteWirelessPolicyToRegistry(
  443. LPWSTR pszWirelessPolicyPath,
  444. LPWSTR pszWirelessPolicyName,
  445. LPWSTR pszWirelessPolicyDescription,
  446. LPWSTR pszWirelessPolicyID
  447. )
  448. {
  449. DWORD dwError = 0;
  450. DWORD dwDisp = 0;
  451. HKEY hKey = NULL;
  452. DWORD dwFlags = 1;
  453. dwError = RegCreateKeyEx (
  454. HKEY_LOCAL_MACHINE,
  455. POLICY_PATH,
  456. 0,
  457. NULL,
  458. REG_OPTION_NON_VOLATILE,
  459. KEY_ALL_ACCESS,
  460. NULL,
  461. &hKey,
  462. &dwDisp
  463. );
  464. if (dwError) {
  465. goto error;
  466. }
  467. if (pszWirelessPolicyPath && *pszWirelessPolicyPath) {
  468. dwError = RegSetValueEx (
  469. hKey,
  470. TEXT("DSWirelessPolicyPath"),
  471. 0,
  472. REG_SZ,
  473. (LPBYTE)pszWirelessPolicyPath,
  474. (lstrlen(pszWirelessPolicyPath) + 1) * sizeof(TCHAR)
  475. );
  476. dwFlags = 1;
  477. dwError = RegSetValueEx (
  478. hKey,
  479. TEXT("DSWirelessPolicyFlags"),
  480. 0,
  481. REG_DWORD,
  482. (LPBYTE)&dwFlags,
  483. sizeof(dwFlags)
  484. );
  485. }
  486. if (pszWirelessPolicyName && *pszWirelessPolicyName) {
  487. dwError = RegSetValueEx (
  488. hKey,
  489. TEXT("DSWirelessPolicyName"),
  490. 0,
  491. REG_SZ,
  492. (LPBYTE)pszWirelessPolicyName,
  493. (lstrlen(pszWirelessPolicyName) + 1) * sizeof(TCHAR)
  494. );
  495. }
  496. if (pszWirelessPolicyID && *pszWirelessPolicyID) {
  497. dwError = RegSetValueEx (
  498. hKey,
  499. TEXT("WirelessID"),
  500. 0,
  501. REG_SZ,
  502. (LPBYTE)pszWirelessPolicyID,
  503. (lstrlen(pszWirelessPolicyID) + 1) * sizeof(TCHAR)
  504. );
  505. }
  506. if (pszWirelessPolicyDescription && *pszWirelessPolicyDescription) {
  507. dwError = RegSetValueEx (
  508. hKey,
  509. TEXT("DSWirelessPolicyDescription"),
  510. 0,
  511. REG_SZ,
  512. (LPBYTE)pszWirelessPolicyDescription,
  513. (lstrlen(pszWirelessPolicyDescription) + 1) * sizeof(TCHAR)
  514. );
  515. }
  516. error:
  517. if (hKey) {
  518. RegCloseKey (hKey);
  519. }
  520. return(dwError);
  521. }
  522. VOID
  523. PingWirelessPolicyAgent(
  524. )
  525. {
  526. HANDLE hPolicyChangeEvent = NULL;
  527. hPolicyChangeEvent = OpenEvent(
  528. EVENT_ALL_ACCESS,
  529. FALSE,
  530. L"WIRELESS_POLICY_CHANGE_EVENT"
  531. );
  532. if (hPolicyChangeEvent) {
  533. SetEvent(hPolicyChangeEvent);
  534. CloseHandle(hPolicyChangeEvent);
  535. }
  536. }