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.

1005 lines
32 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N U C O M P A T . C P P
  7. //
  8. // Contents:
  9. //
  10. //
  11. // Notes:
  12. //
  13. // Author: kumarp 04/12/97 17:17:27
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "comp.h"
  19. #include "conflict.h"
  20. #include "infmap.h"
  21. #include "kkstl.h"
  22. #include "kkutils.h"
  23. #include "ncsetup.h"
  24. #include "oemupg.h"
  25. #include "ncsvc.h"
  26. // ----------------------------------------------------------------------
  27. // String constants
  28. const WCHAR sz_DLC[] = L"DLC";
  29. #ifdef _X86_
  30. #define NWC_PRINT_PROVIDER 101
  31. #define MAX_BUF_SIZE 350
  32. const WCHAR c_szNWCWorkstation[] = L"NWCWorkstation";
  33. const WCHAR c_szNWCfgDll[] = L"System32\\nwcfg.dll";
  34. const WCHAR c_szProviders[] = L"System\\CurrentControlSet\\Control\\Print\\Providers";
  35. const WCHAR c_szNWCPrintProviderKey[] = L"System\\CurrentControlSet\\Control\\Print\\Providers\\Netware or Compatible Network";
  36. const WCHAR c_szOrder[] = L"Order";
  37. const WCHAR c_szTmpPrefix[] = L"$net";
  38. const WCHAR c_szNWCSection[] = L"RenameNWCPrintProvider";
  39. const WCHAR c_szUpdateProviderOrder[] = L"UpdateProvidersOrder";
  40. const WCHAR c_szNWCDelReg[] = L"NWCProviderDelReg";
  41. const WCHAR c_szNWCAddReg[] = L"NWCProviderAddReg";
  42. const WCHAR c_szNWCPrintProviderName[] = L"Netware or Compatible Network";
  43. const WCHAR c_szDefaultDisplayName[] = L"DisplayName";
  44. const WCHAR c_szDefaultName[] = L"Name";
  45. const WCHAR c_szDefaultameValue [] = L"nwprovau.dll";
  46. static DWORD g_dwBytesWritten;
  47. static WCHAR g_buf[MAX_BUF_SIZE+1];
  48. #endif
  49. const WCHAR c_szDefaultTextFile[] = L"compdata\\unsupmsg.txt";
  50. void GetHelpFile(IN PCWSTR pszPreNT5InfId,
  51. OUT tstring* pstrTextHelpFile,
  52. OUT tstring* pstrHtmlHelpFile);
  53. #ifdef _X86_
  54. VOID FixNWClientPrinProviderName (PCOMPAIBILITYCALLBACK CompatibilityCallback, LPVOID Context);
  55. HRESULT DumpProvidersOrder (HANDLE hFile, LPWSTR lpszPrintProviderName);
  56. HRESULT DumpNWPrintProviderKey (HANDLE hFile, LPWSTR lpszPrintProviderName);
  57. BOOL IsNT4Upgrade (VOID);
  58. BOOL IsNetWareClientKeyLocalized (VOID);
  59. HRESULT GetNWPrintProviderName (LPWSTR *lppPrintProvider);
  60. #endif
  61. // ----------------------------------------------------------------------
  62. //
  63. // Function: NetUpgradeCompatibilityCheck
  64. //
  65. // Purpose: This functions is called by winnt32.exe so that we
  66. // can scan the system to find any potential upgrade problems
  67. //
  68. // For each such problem-net-component found, we call
  69. // CompatibilityCallback to report it to winnt32
  70. //
  71. // Arguments:
  72. // CompatibilityCallback [in] pointer to COMPAIBILITYCALLBACK fn
  73. // Context [in] pointer to compatibility context
  74. //
  75. // Returns:
  76. //
  77. // Author: kumarp 21-May-98
  78. //
  79. // Notes:
  80. //
  81. BOOL
  82. WINAPI
  83. NetUpgradeCompatibilityCheck(
  84. PCOMPAIBILITYCALLBACK CompatibilityCallback,
  85. LPVOID Context)
  86. {
  87. DefineFunctionName("NetUpgradeCompatibilityCheck");
  88. TraceTag(ttidNetUpgrade, "entering ---> %s", __FUNCNAME__);
  89. HRESULT hr=S_OK;
  90. TPtrList* plNetComponents;
  91. TPtrListIter pos;
  92. COMPATIBILITY_ENTRY ce;
  93. CNetComponent* pnc;
  94. DWORD dwError;
  95. hr = HrGetConflictsList(&plNetComponents);
  96. if (S_OK == hr)
  97. {
  98. tstring strHtmlHelpFile;
  99. tstring strTextHelpFile;
  100. for (pos = plNetComponents->begin();
  101. pos != plNetComponents->end(); pos++)
  102. {
  103. pnc = (CNetComponent*) *pos;
  104. GetHelpFile(pnc->m_strPreNT5InfId.c_str(),
  105. &strTextHelpFile, &strHtmlHelpFile);
  106. // prepare the entry
  107. //
  108. ZeroMemory(&ce, sizeof(ce));
  109. ce.Description = (PWSTR) pnc->m_strDescription.c_str();
  110. ce.HtmlName = (PWSTR) strHtmlHelpFile.c_str();
  111. ce.TextName = (PWSTR) strTextHelpFile.c_str();
  112. ce.RegKeyName = NULL;
  113. ce.RegValName = NULL;
  114. ce.RegValDataSize = 0;
  115. ce.RegValData = 0;
  116. ce.SaveValue = (LPVOID) pnc;
  117. ce.Flags = COMPFLAG_USE_HAVEDISK;
  118. TraceTag(ttidNetUpgrade,
  119. "%s: calling CompatibilityCallback for '%S': %S, %S...",
  120. __FUNCNAME__, ce.Description, ce.HtmlName, ce.TextName);
  121. dwError = CompatibilityCallback(&ce, Context);
  122. TraceTag(ttidNetUpgrade, "...CompatibilityCallback returned 0x%x",
  123. dwError);
  124. }
  125. }
  126. else if (FAILED(hr))
  127. {
  128. TraceTag(ttidNetUpgrade, "%s: HrGetConflictsList returned err code: 0x%x",
  129. __FUNCNAME__, hr);
  130. }
  131. #ifdef _X86_
  132. // Raid Bug 327760: Change localized Netware Print Provider name to English.
  133. FixNWClientPrinProviderName( CompatibilityCallback, Context );
  134. #endif
  135. return SUCCEEDED(hr);
  136. }
  137. // ----------------------------------------------------------------------
  138. //
  139. // Function: NetUpgradeHandleCompatibilityHaveDisk
  140. //
  141. // Purpose: This callback function is called by winnt32.exe
  142. // if user clicks HaveDisk button on the compatibility
  143. // report page.
  144. //
  145. // Arguments:
  146. // hwndParent [in] handle of parent window
  147. // SaveValue [in] pointer to private data
  148. // (we store CNetComponent* in this pointer)
  149. //
  150. // Returns:
  151. //
  152. // Author: kumarp 21-May-98
  153. //
  154. // Notes:
  155. //
  156. DWORD
  157. WINAPI
  158. NetUpgradeHandleCompatibilityHaveDisk(HWND hwndParent,
  159. LPVOID SaveValue)
  160. {
  161. DefineFunctionName("NetUpgradeHandleCompatibilityHaveDisk");
  162. HRESULT hr=S_OK;
  163. BOOL fStatus = FALSE;
  164. DWORD dwStatus=ERROR_SUCCESS;
  165. CNetComponent* pnc=NULL;
  166. PCWSTR pszComponentDescription;
  167. static const WCHAR c_szNull[] = L"<Null>";
  168. if (SaveValue)
  169. {
  170. pnc = (CNetComponent*) SaveValue;
  171. pszComponentDescription = pnc->m_strDescription.c_str();
  172. }
  173. else
  174. {
  175. pszComponentDescription = c_szNull;
  176. }
  177. TraceTag(ttidNetUpgrade, "%s: called for %S...",
  178. __FUNCNAME__, pszComponentDescription);
  179. if (pnc)
  180. {
  181. tstring strOemDir;
  182. hr = HrShowUiAndGetOemFileLocation(hwndParent,
  183. pszComponentDescription,
  184. &strOemDir);
  185. if (S_OK == hr)
  186. {
  187. hr = HrProcessAndCopyOemFiles(strOemDir.c_str(), TRUE);
  188. }
  189. }
  190. else
  191. {
  192. hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  193. }
  194. TraceErrorOptional(__FUNCNAME__, hr, (S_FALSE == hr));
  195. if (S_FALSE == hr)
  196. {
  197. // this will ensure that winnt32 will not take this item
  198. // off the compatibility list
  199. //
  200. dwStatus = ERROR_FILE_NOT_FOUND;
  201. }
  202. else
  203. {
  204. dwStatus = DwWin32ErrorFromHr(hr);
  205. }
  206. return dwStatus;
  207. }
  208. // ----------------------------------------------------------------------
  209. //
  210. // Function: GetHelpFile
  211. //
  212. // Purpose: Get name of help file for an unsupported component
  213. //
  214. // Arguments:
  215. // hinfNetUpg [in] handle of netupg.inf
  216. // pszPreNT5InfId [in] pre-NT5 InfId
  217. // pstrTextHelpFile [out] name of the text file found
  218. // pstrHtmlHelpFile [out] name of the html file found
  219. //
  220. // Returns: None
  221. //
  222. // Author: kumarp 22-May-98
  223. //
  224. // Notes:
  225. //
  226. void GetHelpFile(IN PCWSTR pszPreNT5InfId,
  227. OUT tstring* pstrTextHelpFile,
  228. OUT tstring* pstrHtmlHelpFile)
  229. {
  230. // Known txt/htm files
  231. if (lstrcmpiW(pszPreNT5InfId, sz_DLC) == 0)
  232. {
  233. *pstrTextHelpFile = L"compdata\\dlcproto.txt";
  234. *pstrHtmlHelpFile = L"compdata\\dlcproto.htm";
  235. return;
  236. }
  237. // Unknown or OEM files
  238. static const WCHAR c_szOemUpgradeHelpFiles[] = L"OemUpgradeHelpFiles";
  239. static const WCHAR c_szDefaultHtmlFile[] = L"compdata\\unsupmsg.htm";
  240. HRESULT hr=S_OK;
  241. INFCONTEXT ic;
  242. tstring strText;
  243. tstring strHtml;
  244. tstring strNT5InfId;
  245. BOOL fIsOemComponent=FALSE;
  246. CNetMapInfo* pnmi=NULL;
  247. *pstrTextHelpFile = c_szDefaultTextFile;
  248. *pstrHtmlHelpFile = c_szDefaultHtmlFile;
  249. hr = HrMapPreNT5NetComponentInfIDToNT5InfID(pszPreNT5InfId,
  250. &strNT5InfId,
  251. &fIsOemComponent,
  252. NULL, &pnmi);
  253. if ((S_FALSE == hr) && !strNT5InfId.empty())
  254. {
  255. hr = HrSetupFindFirstLine(pnmi->m_hinfNetMap, c_szOemUpgradeHelpFiles,
  256. strNT5InfId.c_str(), &ic);
  257. if (S_OK == hr)
  258. {
  259. hr = HrSetupGetStringField(ic, 1, &strText);
  260. if (S_OK == hr)
  261. {
  262. hr = HrSetupGetStringField(ic, 2, &strHtml);
  263. if (S_OK == hr)
  264. {
  265. *pstrTextHelpFile = pnmi->m_strOemDir;
  266. *pstrHtmlHelpFile = pnmi->m_strOemDir;
  267. AppendToPath(pstrTextHelpFile, strText.c_str());
  268. AppendToPath(pstrHtmlHelpFile, strHtml.c_str());
  269. }
  270. }
  271. }
  272. }
  273. }
  274. #ifdef _X86_
  275. // ----------------------------------------------------------------------
  276. //
  277. // Function: FixNWClientPrinProviderName
  278. //
  279. // Purpose: Change the localized Print Provider name to English.
  280. //
  281. // Arguments:
  282. //
  283. // Returns: None
  284. //
  285. // Author: asinha 14-June-01
  286. //
  287. // Notes:
  288. //
  289. VOID FixNWClientPrinProviderName (PCOMPAIBILITYCALLBACK CompatibilityCallback,
  290. LPVOID Context)
  291. {
  292. DefineFunctionName( "FixNWClientPrinProviderName" );
  293. TraceTag(ttidNetUpgrade, "entering ---> %s", __FUNCNAME__);
  294. LPWSTR lpszPrintProviderName;
  295. WCHAR lpTmpFile[MAX_PATH+1];
  296. WCHAR lpTmpPath[MAX_PATH+1];
  297. HANDLE hFile;
  298. DWORD dwChars;
  299. COMPATIBILITY_ENTRY ce;
  300. BOOL bRet;
  301. HRESULT hr=S_OK;
  302. //
  303. // Is it an upgrade from NT 4.0 and the Netware print provider name localized?
  304. //
  305. if ( IsNT4Upgrade() && IsNetWareClientKeyLocalized() )
  306. {
  307. TraceTag( ttidNetUpgrade, "%s: Netware Print Provider name is localized.",
  308. __FUNCNAME__ );
  309. // Get the localized Netware print provider name from nwcfg.dll.
  310. hr = GetNWPrintProviderName( &lpszPrintProviderName );
  311. if ( hr == S_OK )
  312. {
  313. TraceTag( ttidNetUpgrade, "%s: Netware Print Provider name is: %S",
  314. __FUNCNAME__, lpszPrintProviderName );
  315. // Create a .tmp filename where INF directives are written to rename
  316. // the print provider name into English. This INF file will be executed
  317. // by base setup in GUI mode.
  318. //
  319. GetTempPathW( MAX_PATH, lpTmpPath );
  320. if ( GetTempFileNameW( lpTmpPath, c_szTmpPrefix, 1, lpTmpFile) )
  321. {
  322. hFile = CreateFileW( lpTmpFile,
  323. GENERIC_WRITE | GENERIC_WRITE,
  324. 0,
  325. NULL,
  326. CREATE_ALWAYS,
  327. FILE_ATTRIBUTE_NORMAL,
  328. NULL );
  329. if ( hFile != INVALID_HANDLE_VALUE )
  330. {
  331. // Write the initial entries.
  332. dwChars = wsprintfW( g_buf, L"[Version]\r\n"
  333. L"Signature=\"$WINDOWS NT$\"\r\n"
  334. L"Provider=Microsoft\r\n"
  335. L"LayoutFile=layout.inf\r\n\r\n"
  336. L"[%s]\r\n"
  337. L"AddReg=%s\r\n"
  338. L"DelReg=%s\r\n"
  339. L"AddReg=%s\r\n",
  340. c_szNWCSection,
  341. c_szUpdateProviderOrder,
  342. c_szNWCDelReg,
  343. c_szNWCAddReg );
  344. Assert( dwChars <= MAX_BUF_SIZE );
  345. WriteFile( hFile,
  346. g_buf,
  347. dwChars * sizeof(WCHAR),
  348. &g_dwBytesWritten,
  349. NULL );
  350. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  351. // Write the HKLM\System\CCS\Control\Print\Providers\Order values.
  352. hr = DumpProvidersOrder( hFile, lpszPrintProviderName );
  353. if ( hr == S_OK )
  354. {
  355. // Write addreg/delreg directives to change the Print Provider name
  356. hr = DumpNWPrintProviderKey( hFile, lpszPrintProviderName );
  357. if ( hr == S_OK )
  358. {
  359. CloseHandle( hFile );
  360. hFile = INVALID_HANDLE_VALUE;
  361. // Call the compatibility callback so the %temp%\$ne1.tmp INF file
  362. // is executed in GUI mode setup.
  363. ZeroMemory( &ce, sizeof(ce) );
  364. ce.Description = (PWSTR)c_szNWCPrintProviderName;
  365. ce.TextName = (PWSTR)c_szDefaultTextFile;
  366. ce.InfName = (PWSTR)lpTmpFile;
  367. ce.InfSection = (PWSTR)c_szNWCSection;
  368. ce.Flags = COMPFLAG_HIDE;
  369. TraceTag(ttidNetUpgrade,
  370. "%s: calling CompatibilityCallback for '%S'...",
  371. __FUNCNAME__, ce.Description );
  372. bRet = CompatibilityCallback( &ce, Context );
  373. TraceTag( ttidNetUpgrade, "...CompatibilityCallback returned %#x",
  374. bRet );
  375. }
  376. }
  377. if ( hFile != INVALID_HANDLE_VALUE )
  378. {
  379. CloseHandle( hFile );
  380. }
  381. }
  382. else
  383. {
  384. TraceTag( ttidNetUpgrade, "%s: Failed to open %S.",
  385. __FUNCNAME__, lpTmpFile );
  386. hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  387. }
  388. }
  389. else
  390. {
  391. hr = HRESULT_FROM_WIN32(GetLastError());
  392. TraceTag( ttidNetUpgrade, "%s: GetTempFileName failed, path=%S, prefix=%S: Error=%#x",
  393. __FUNCNAME__, lpTmpPath, c_szTmpPrefix, hr );
  394. }
  395. MemFree( lpszPrintProviderName );
  396. }
  397. else
  398. {
  399. TraceTag( ttidNetUpgrade, "%s: GetNWPrintProviderName returned error : %#x",
  400. __FUNCNAME__, hr );
  401. }
  402. }
  403. TraceTag(ttidNetUpgrade, "<---%s: hr = %#x",
  404. __FUNCNAME__, hr);
  405. return;
  406. }
  407. // Write addreg to update HKLM\System\CCS\Control\Print\Order value with the Netware Print Provider
  408. // in English.
  409. HRESULT DumpProvidersOrder (HANDLE hFile, LPWSTR lpszPrintProviderName)
  410. {
  411. DefineFunctionName( "DumpProvidersOrder" );
  412. TraceTag(ttidNetUpgrade, "entering ---> %s", __FUNCNAME__);
  413. HKEY hkeyProviders;
  414. DWORD dwValueLen;
  415. LPWSTR lpValue;
  416. LPWSTR lpTemp;
  417. DWORD dwChars;
  418. LONG lResult;
  419. dwChars = wsprintfW( g_buf, L"\r\n[%s]\r\n", c_szUpdateProviderOrder );
  420. Assert( dwChars <= MAX_BUF_SIZE );
  421. WriteFile( hFile,
  422. g_buf,
  423. dwChars * sizeof(WCHAR),
  424. &g_dwBytesWritten,
  425. NULL );
  426. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  427. lResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
  428. c_szProviders,
  429. 0,
  430. KEY_READ,
  431. &hkeyProviders );
  432. if ( lResult == ERROR_SUCCESS )
  433. {
  434. // First query how many bytes are needed to read the value.
  435. lResult = RegQueryValueExW( hkeyProviders, // handle to key
  436. c_szOrder, // value name
  437. NULL, // reserved
  438. NULL, // type buffer
  439. NULL, // data buffer
  440. &dwValueLen ); // size of data buffer
  441. if ( lResult == ERROR_SUCCESS )
  442. {
  443. lpValue = (LPWSTR)MemAlloc( dwValueLen );
  444. if ( lpValue )
  445. {
  446. // Read the old value which is a multi_sz.
  447. lResult = RegQueryValueExW( hkeyProviders, // handle to key
  448. c_szOrder, // value name
  449. NULL, // reserved
  450. NULL, // type buffer
  451. (LPBYTE)lpValue,// data buffer
  452. &dwValueLen ); // size of data buffer
  453. if ( lResult == ERROR_SUCCESS )
  454. {
  455. lpTemp = lpValue;
  456. dwChars = wsprintfW( g_buf,
  457. L"HKLM,\"%s\",\"%s\",0x00010020",
  458. c_szProviders, c_szOrder );
  459. Assert( dwChars <= MAX_BUF_SIZE );
  460. WriteFile( hFile,
  461. g_buf,
  462. dwChars * sizeof(WCHAR),
  463. &g_dwBytesWritten,
  464. NULL );
  465. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  466. // Write each print provider name.
  467. while( *lpTemp )
  468. {
  469. // If we find a localized one then, we write its English name.
  470. if ( _wcsicmp( lpTemp, lpszPrintProviderName) != 0 )
  471. {
  472. dwChars = _snwprintf( g_buf, MAX_BUF_SIZE+1, L",\"%s\"", lpTemp );
  473. g_buf[MAX_BUF_SIZE] = L'\0';
  474. if ( dwChars > MAX_BUF_SIZE )
  475. {
  476. dwChars = MAX_BUF_SIZE;
  477. Assert( FALSE );
  478. }
  479. TraceTag( ttidNetUpgrade, "%s: Writing print provider name %S.",
  480. __FUNCNAME__, lpTemp );
  481. }
  482. else
  483. {
  484. dwChars = wsprintfW( g_buf, L",\"%s\"", c_szNWCPrintProviderName );
  485. Assert( dwChars <= MAX_BUF_SIZE );
  486. TraceTag( ttidNetUpgrade, "%s: Writing print provider name %S.",
  487. __FUNCNAME__, c_szNWCPrintProviderName );
  488. }
  489. WriteFile( hFile,
  490. g_buf,
  491. dwChars * sizeof(WCHAR),
  492. &g_dwBytesWritten,
  493. NULL );
  494. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  495. // Get next print provider name.
  496. lpTemp += lstrlenW( lpTemp ) + 1;
  497. }
  498. dwChars = wsprintfW( g_buf, L"\r\n" );
  499. Assert( dwChars <= MAX_BUF_SIZE );
  500. WriteFile( hFile,
  501. g_buf,
  502. dwChars * sizeof(WCHAR),
  503. &g_dwBytesWritten,
  504. NULL );
  505. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  506. }
  507. else
  508. {
  509. TraceTag( ttidNetUpgrade, "%s: RegQueryValueExW failed to open '%S' value, Error: %#x",
  510. c_szOrder, HRESULT_FROM_WIN32(lResult) );
  511. }
  512. MemFree( lpValue );
  513. }
  514. else
  515. {
  516. lResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  517. }
  518. }
  519. else
  520. {
  521. TraceTag(ttidNetUpgrade, "RegQueryValueExW failed to open '%S' value, Error: %#x",
  522. __FUNCNAME__, c_szOrder, HRESULT_FROM_WIN32(lResult) );
  523. }
  524. RegCloseKey( hkeyProviders );
  525. }
  526. else
  527. {
  528. TraceTag(ttidNetUpgrade, "%s: RegOpenKeyExW failed to open '%S' key, Error: %#x",
  529. __FUNCNAME__, c_szProviders, HRESULT_FROM_WIN32(lResult) );
  530. }
  531. TraceTag(ttidNetUpgrade, "<---%s: hr = %#x",
  532. __FUNCNAME__, HRESULT_FROM_WIN32(lResult));
  533. return HRESULT_FROM_WIN32(lResult);
  534. }
  535. // Write delreg/addreg directives to rename the Netware PrintProvider name into English.
  536. HRESULT DumpNWPrintProviderKey (HANDLE hFile, LPWSTR lpszPrintProviderName)
  537. {
  538. DefineFunctionName( "DumpNWPrintProviderKey" );
  539. TraceTag(ttidNetUpgrade, "entering ---> %s", __FUNCNAME__);
  540. HKEY hkeyNWPrinProvider;
  541. WCHAR szNWPrintProvider[MAX_PATH+1];
  542. DWORD dwMaxValueNameLen;
  543. DWORD dwMaxValueLen;
  544. DWORD dwNameLen;
  545. DWORD dwValueLen;
  546. DWORD dwCount;
  547. DWORD i;
  548. DWORD dwChars;
  549. LPWSTR lpValueName;
  550. LPWSTR lpValue;
  551. LONG lResult;
  552. _snwprintf( szNWPrintProvider, MAX_PATH+1 , L"%s\\%s",
  553. c_szProviders,
  554. lpszPrintProviderName );
  555. szNWPrintProvider[MAX_PATH] = L'\0';
  556. dwChars = _snwprintf( g_buf, MAX_BUF_SIZE+1, L"\r\n[%s]\r\n"
  557. L"HKLM,\"%s\"\r\n",
  558. c_szNWCDelReg, szNWPrintProvider );
  559. g_buf[MAX_BUF_SIZE] = L'\0';
  560. if ( dwChars > MAX_BUF_SIZE )
  561. {
  562. dwChars = MAX_BUF_SIZE;
  563. Assert( FALSE );
  564. }
  565. WriteFile( hFile,
  566. g_buf,
  567. dwChars * sizeof(WCHAR),
  568. &g_dwBytesWritten,
  569. NULL );
  570. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  571. dwChars = wsprintfW( g_buf, L"\r\n[%s]\r\n", c_szNWCAddReg );
  572. Assert( dwChars <= MAX_BUF_SIZE );
  573. WriteFile( hFile,
  574. g_buf,
  575. dwChars * sizeof(WCHAR),
  576. &g_dwBytesWritten,
  577. NULL );
  578. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  579. // Open the localize Netware print provider key.
  580. lResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
  581. szNWPrintProvider,
  582. 0,
  583. KEY_READ,
  584. &hkeyNWPrinProvider );
  585. if ( lResult == ERROR_SUCCESS )
  586. {
  587. // Find out the space needed for longest name and largest value and how many values.
  588. lResult = RegQueryInfoKeyW( hkeyNWPrinProvider,
  589. NULL,
  590. NULL,
  591. NULL,
  592. NULL,
  593. NULL,
  594. NULL,
  595. &dwCount,
  596. &dwMaxValueNameLen,
  597. &dwMaxValueLen,
  598. NULL,
  599. NULL );
  600. if ( lResult == ERROR_SUCCESS )
  601. {
  602. // Add some padding.
  603. dwMaxValueLen += 4;
  604. dwMaxValueNameLen += 4;
  605. lpValueName = (LPWSTR)MemAlloc( dwMaxValueNameLen * sizeof(WCHAR) );
  606. lpValue = (LPWSTR)MemAlloc( dwMaxValueLen );
  607. if ( lpValueName && lpValue )
  608. {
  609. // Enumerate each value and write it to the INF file.
  610. for (i=0; i < dwCount; ++i)
  611. {
  612. dwNameLen = dwMaxValueNameLen;
  613. dwValueLen = dwMaxValueLen;
  614. lResult = RegEnumValueW(hkeyNWPrinProvider,
  615. i,
  616. lpValueName,
  617. &dwNameLen,
  618. NULL,
  619. NULL,
  620. (LPBYTE)lpValue,
  621. &dwValueLen );
  622. Assert( lResult == ERROR_SUCCESS );
  623. if ( lResult == ERROR_SUCCESS )
  624. {
  625. dwChars = _snwprintf( g_buf, MAX_BUF_SIZE+1,
  626. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  627. c_szNWCPrintProviderKey, lpValueName, lpValue );
  628. g_buf[MAX_BUF_SIZE] = L'\0';
  629. if ( dwChars > MAX_BUF_SIZE )
  630. {
  631. dwChars = MAX_BUF_SIZE;
  632. Assert( FALSE );
  633. }
  634. WriteFile( hFile,
  635. g_buf,
  636. dwChars * sizeof(WCHAR),
  637. &g_dwBytesWritten,
  638. NULL );
  639. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  640. TraceTag( ttidNetUpgrade, "%s: Writing value name %S, value %S",
  641. __FUNCNAME__, lpValueName, lpValue );
  642. }
  643. else
  644. {
  645. TraceTag( ttidNetUpgrade, "%s: RegEnumValueW(%d) failed. Error: %#x",
  646. __FUNCNAME__, i, HRESULT_FROM_WIN32(lResult) );
  647. }
  648. }
  649. lResult = ERROR_SUCCESS;
  650. }
  651. else
  652. {
  653. lResult = ERROR_NOT_ENOUGH_MEMORY;
  654. }
  655. if ( lpValueName )
  656. {
  657. MemFree( lpValueName );
  658. }
  659. if ( lpValue )
  660. {
  661. MemFree( lpValue );
  662. }
  663. }
  664. RegCloseKey( hkeyNWPrinProvider );
  665. }
  666. else
  667. {
  668. // For some reason, we couldn't open the localized Netware Print Provider name. So, we
  669. // write the default values.
  670. //
  671. TraceTag(ttidNetUpgrade,"%s: RegOpenKeyExW failed to open '%S' key, Error: %#x",
  672. __FUNCNAME__, szNWPrintProvider, HRESULT_FROM_WIN32(lResult) );
  673. dwChars = _snwprintf( g_buf, MAX_BUF_SIZE+1,
  674. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  675. c_szNWCPrintProviderKey, c_szDefaultDisplayName, lpszPrintProviderName );
  676. g_buf[MAX_BUF_SIZE] = L'\0';
  677. if ( dwChars > MAX_BUF_SIZE )
  678. {
  679. dwChars = MAX_BUF_SIZE;
  680. Assert( FALSE );
  681. }
  682. WriteFile( hFile,
  683. g_buf,
  684. dwChars * sizeof(WCHAR),
  685. &g_dwBytesWritten,
  686. NULL );
  687. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  688. dwChars = wsprintfW( g_buf,
  689. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  690. c_szNWCPrintProviderKey, c_szDefaultName, c_szDefaultameValue );
  691. Assert( dwChars <= MAX_BUF_SIZE );
  692. WriteFile( hFile,
  693. g_buf,
  694. dwChars * sizeof(WCHAR),
  695. &g_dwBytesWritten,
  696. NULL );
  697. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  698. lResult = ERROR_SUCCESS;
  699. }
  700. TraceTag(ttidNetUpgrade, "<---%s: hr = %#x",
  701. __FUNCNAME__, HRESULT_FROM_WIN32(lResult));
  702. return HRESULT_FROM_WIN32(lResult);
  703. }
  704. BOOL IsNT4Upgrade (VOID)
  705. {
  706. OSVERSIONINFO osvi;
  707. ZeroMemory( &osvi,
  708. sizeof(OSVERSIONINFO) );
  709. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  710. if ( GetVersionEx(&osvi) )
  711. {
  712. return ( (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  713. (osvi.dwMajorVersion == 4) &&
  714. (osvi.dwMinorVersion == 0) );
  715. }
  716. return TRUE;
  717. }
  718. // Determine if Netware print provider name is localized.
  719. BOOL IsNetWareClientKeyLocalized (VOID)
  720. {
  721. CServiceManager sm;
  722. CService srv;
  723. HKEY hKey;
  724. HRESULT hr;
  725. LONG lResult = ERROR_SUCCESS;
  726. // Is CSNW installed?
  727. if ( sm.HrOpenService(&srv,
  728. c_szNWCWorkstation) == S_OK )
  729. {
  730. srv.Close();
  731. // Open the Netware print provider name key assuming it is in English.
  732. lResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
  733. c_szNWCPrintProviderKey,
  734. 0,
  735. KEY_READ,
  736. &hKey );
  737. if ( lResult == ERROR_SUCCESS )
  738. {
  739. RegCloseKey( hKey );
  740. }
  741. }
  742. // If we successfully opened the key then, it is not localized.
  743. return lResult != ERROR_SUCCESS;
  744. }
  745. // Get the localized Netware Print provider name from nwcfg.dll.
  746. HRESULT GetNWPrintProviderName (LPWSTR *lppPrintProvider)
  747. {
  748. LPWSTR lpszNWCfgDll;
  749. int iLen;
  750. HMODULE hModule;
  751. WCHAR lpszNWCName[100];
  752. DWORD dwLen;
  753. HRESULT hr;
  754. *lppPrintProvider = NULL;
  755. dwLen = GetWindowsDirectoryW( NULL, 0 );
  756. if ( dwLen == 0 )
  757. {
  758. return HRESULT_FROM_WIN32(GetLastError());
  759. }
  760. lpszNWCfgDll = (LPWSTR)MemAlloc( (dwLen + celems(c_szNWCfgDll) + 2)
  761. * sizeof(WCHAR) );
  762. if ( !lpszNWCfgDll )
  763. {
  764. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  765. }
  766. if ( GetWindowsDirectoryW(lpszNWCfgDll, dwLen) == 0 )
  767. {
  768. hr = HRESULT_FROM_WIN32(GetLastError());
  769. }
  770. else
  771. {
  772. if ( lpszNWCfgDll[dwLen-1] == L'\\' )
  773. {
  774. lstrcatW( lpszNWCfgDll, c_szNWCfgDll );
  775. }
  776. else
  777. {
  778. lstrcatW( lpszNWCfgDll, L"\\" );
  779. lstrcatW( lpszNWCfgDll, c_szNWCfgDll );
  780. }
  781. hModule = LoadLibraryExW( lpszNWCfgDll, NULL, LOAD_LIBRARY_AS_DATAFILE );
  782. if ( hModule )
  783. {
  784. iLen = LoadStringW( hModule, NWC_PRINT_PROVIDER, lpszNWCName, 100 );
  785. if ( iLen > 0 )
  786. {
  787. *lppPrintProvider = (LPWSTR)MemAlloc( (iLen + 1) * sizeof(WCHAR) );
  788. if ( *lppPrintProvider )
  789. {
  790. lstrcpyW( *lppPrintProvider, lpszNWCName );
  791. hr = S_OK;
  792. }
  793. else
  794. {
  795. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  796. }
  797. }
  798. else
  799. {
  800. hr = HRESULT_FROM_WIN32( GetLastError() );
  801. }
  802. FreeLibrary( hModule );
  803. }
  804. else
  805. {
  806. hr = HRESULT_FROM_WIN32( GetLastError() );
  807. }
  808. }
  809. MemFree( lpszNWCfgDll );
  810. return hr;
  811. }
  812. #endif