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.

980 lines
30 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"winntupg\\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"winntupg\\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 = wsprintfW( g_buf, L",\"%s\"", lpTemp );
  473. Assert( dwChars <= MAX_BUF_SIZE );
  474. TraceTag( ttidNetUpgrade, "%s: Writing print provider name %S.",
  475. __FUNCNAME__, lpTemp );
  476. }
  477. else
  478. {
  479. dwChars = wsprintfW( g_buf, L",\"%s\"", c_szNWCPrintProviderName );
  480. Assert( dwChars <= MAX_BUF_SIZE );
  481. TraceTag( ttidNetUpgrade, "%s: Writing print provider name %S.",
  482. __FUNCNAME__, c_szNWCPrintProviderName );
  483. }
  484. WriteFile( hFile,
  485. g_buf,
  486. dwChars * sizeof(WCHAR),
  487. &g_dwBytesWritten,
  488. NULL );
  489. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  490. // Get next print provider name.
  491. lpTemp += lstrlenW( lpTemp ) + 1;
  492. }
  493. dwChars = wsprintfW( g_buf, L"\r\n" );
  494. Assert( dwChars <= MAX_BUF_SIZE );
  495. WriteFile( hFile,
  496. g_buf,
  497. dwChars * sizeof(WCHAR),
  498. &g_dwBytesWritten,
  499. NULL );
  500. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  501. }
  502. else
  503. {
  504. TraceTag( ttidNetUpgrade, "%s: RegQueryValueExW failed to open '%S' value, Error: %#x",
  505. c_szOrder, HRESULT_FROM_WIN32(lResult) );
  506. }
  507. MemFree( lpValue );
  508. }
  509. else
  510. {
  511. lResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  512. }
  513. }
  514. else
  515. {
  516. TraceTag(ttidNetUpgrade, "RegQueryValueExW failed to open '%S' value, Error: %#x",
  517. __FUNCNAME__, c_szOrder, HRESULT_FROM_WIN32(lResult) );
  518. }
  519. RegCloseKey( hkeyProviders );
  520. }
  521. else
  522. {
  523. TraceTag(ttidNetUpgrade, "%s: RegOpenKeyExW failed to open '%S' key, Error: %#x",
  524. __FUNCNAME__, c_szProviders, HRESULT_FROM_WIN32(lResult) );
  525. }
  526. TraceTag(ttidNetUpgrade, "<---%s: hr = %#x",
  527. __FUNCNAME__, HRESULT_FROM_WIN32(lResult));
  528. return HRESULT_FROM_WIN32(lResult);
  529. }
  530. // Write delreg/addreg directives to rename the Netware PrintProvider name into English.
  531. HRESULT DumpNWPrintProviderKey (HANDLE hFile, LPWSTR lpszPrintProviderName)
  532. {
  533. DefineFunctionName( "DumpNWPrintProviderKey" );
  534. TraceTag(ttidNetUpgrade, "entering ---> %s", __FUNCNAME__);
  535. HKEY hkeyNWPrinProvider;
  536. WCHAR szNWPrintProvider[MAX_PATH+1];
  537. DWORD dwMaxValueNameLen;
  538. DWORD dwMaxValueLen;
  539. DWORD dwNameLen;
  540. DWORD dwValueLen;
  541. DWORD dwCount;
  542. DWORD i;
  543. DWORD dwChars;
  544. LPWSTR lpValueName;
  545. LPWSTR lpValue;
  546. LONG lResult;
  547. dwChars = wsprintfW( szNWPrintProvider, L"%s\\%s",
  548. c_szProviders,
  549. lpszPrintProviderName );
  550. Assert( dwChars <= MAX_BUF_SIZE );
  551. dwChars = wsprintfW( g_buf, L"\r\n[%s]\r\n"
  552. L"HKLM,\"%s\"\r\n",
  553. c_szNWCDelReg, szNWPrintProvider );
  554. Assert( dwChars <= MAX_BUF_SIZE );
  555. WriteFile( hFile,
  556. g_buf,
  557. dwChars * sizeof(WCHAR),
  558. &g_dwBytesWritten,
  559. NULL );
  560. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  561. dwChars = wsprintfW( g_buf, L"\r\n[%s]\r\n", c_szNWCAddReg );
  562. Assert( dwChars <= MAX_BUF_SIZE );
  563. WriteFile( hFile,
  564. g_buf,
  565. dwChars * sizeof(WCHAR),
  566. &g_dwBytesWritten,
  567. NULL );
  568. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  569. // Open the localize Netware print provider key.
  570. lResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
  571. szNWPrintProvider,
  572. 0,
  573. KEY_READ,
  574. &hkeyNWPrinProvider );
  575. if ( lResult == ERROR_SUCCESS )
  576. {
  577. // Find out the space needed for longest name and largest value and how many values.
  578. lResult = RegQueryInfoKeyW( hkeyNWPrinProvider,
  579. NULL,
  580. NULL,
  581. NULL,
  582. NULL,
  583. NULL,
  584. NULL,
  585. &dwCount,
  586. &dwMaxValueNameLen,
  587. &dwMaxValueLen,
  588. NULL,
  589. NULL );
  590. if ( lResult == ERROR_SUCCESS )
  591. {
  592. // Add some padding.
  593. dwMaxValueLen += 4;
  594. dwMaxValueNameLen += 4;
  595. lpValueName = (LPWSTR)MemAlloc( dwMaxValueNameLen * sizeof(WCHAR) );
  596. lpValue = (LPWSTR)MemAlloc( dwMaxValueLen );
  597. if ( lpValueName && lpValue )
  598. {
  599. // Enumerate each value and write it to the INF file.
  600. for (i=0; i < dwCount; ++i)
  601. {
  602. dwNameLen = dwMaxValueNameLen;
  603. dwValueLen = dwMaxValueLen;
  604. lResult = RegEnumValueW(hkeyNWPrinProvider,
  605. i,
  606. lpValueName,
  607. &dwNameLen,
  608. NULL,
  609. NULL,
  610. (LPBYTE)lpValue,
  611. &dwValueLen );
  612. Assert( lResult == ERROR_SUCCESS );
  613. if ( lResult == ERROR_SUCCESS )
  614. {
  615. dwChars = wsprintfW( g_buf,
  616. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  617. c_szNWCPrintProviderKey, lpValueName, lpValue );
  618. Assert( dwChars <= MAX_BUF_SIZE );
  619. WriteFile( hFile,
  620. g_buf,
  621. dwChars * sizeof(WCHAR),
  622. &g_dwBytesWritten,
  623. NULL );
  624. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  625. TraceTag( ttidNetUpgrade, "%s: Writing value name %S, value %S",
  626. __FUNCNAME__, lpValueName, lpValue );
  627. }
  628. else
  629. {
  630. TraceTag( ttidNetUpgrade, "%s: RegEnumValueW(%d) failed. Error: %#x",
  631. __FUNCNAME__, i, HRESULT_FROM_WIN32(lResult) );
  632. }
  633. }
  634. lResult = ERROR_SUCCESS;
  635. }
  636. else
  637. {
  638. lResult = ERROR_NOT_ENOUGH_MEMORY;
  639. }
  640. if ( lpValueName )
  641. {
  642. MemFree( lpValueName );
  643. }
  644. if ( lpValue )
  645. {
  646. MemFree( lpValue );
  647. }
  648. }
  649. RegCloseKey( hkeyNWPrinProvider );
  650. }
  651. else
  652. {
  653. // For some reason, we couldn't open the localized Netware Print Provider name. So, we
  654. // write the default values.
  655. //
  656. TraceTag(ttidNetUpgrade,"%s: RegOpenKeyExW failed to open '%S' key, Error: %#x",
  657. __FUNCNAME__, szNWPrintProvider, HRESULT_FROM_WIN32(lResult) );
  658. dwChars = wsprintfW( g_buf,
  659. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  660. c_szNWCPrintProviderKey, c_szDefaultDisplayName, lpszPrintProviderName );
  661. Assert( dwChars <= MAX_BUF_SIZE );
  662. WriteFile( hFile,
  663. g_buf,
  664. dwChars * sizeof(WCHAR),
  665. &g_dwBytesWritten,
  666. NULL );
  667. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  668. dwChars = wsprintfW( g_buf,
  669. L"HKLM,\"%s\",\"%s\",,\"%s\"\r\n",
  670. c_szNWCPrintProviderKey, c_szDefaultName, c_szDefaultameValue );
  671. Assert( dwChars <= MAX_BUF_SIZE );
  672. WriteFile( hFile,
  673. g_buf,
  674. dwChars * sizeof(WCHAR),
  675. &g_dwBytesWritten,
  676. NULL );
  677. Assert( g_dwBytesWritten == (dwChars * sizeof(WCHAR)) );
  678. lResult = ERROR_SUCCESS;
  679. }
  680. TraceTag(ttidNetUpgrade, "<---%s: hr = %#x",
  681. __FUNCNAME__, HRESULT_FROM_WIN32(lResult));
  682. return HRESULT_FROM_WIN32(lResult);
  683. }
  684. BOOL IsNT4Upgrade (VOID)
  685. {
  686. OSVERSIONINFO osvi;
  687. ZeroMemory( &osvi,
  688. sizeof(OSVERSIONINFO) );
  689. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  690. if ( GetVersionEx(&osvi) )
  691. {
  692. return ( (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  693. (osvi.dwMajorVersion == 4) &&
  694. (osvi.dwMinorVersion == 0) );
  695. }
  696. return TRUE;
  697. }
  698. // Determine if Netware print provider name is localized.
  699. BOOL IsNetWareClientKeyLocalized (VOID)
  700. {
  701. CServiceManager sm;
  702. CService srv;
  703. HKEY hKey;
  704. HRESULT hr;
  705. LONG lResult = ERROR_SUCCESS;
  706. // Is CSNW installed?
  707. if ( sm.HrOpenService(&srv,
  708. c_szNWCWorkstation) == S_OK )
  709. {
  710. srv.Close();
  711. // Open the Netware print provider name key assuming it is in English.
  712. lResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
  713. c_szNWCPrintProviderKey,
  714. 0,
  715. KEY_READ,
  716. &hKey );
  717. if ( lResult == ERROR_SUCCESS )
  718. {
  719. RegCloseKey( hKey );
  720. }
  721. }
  722. // If we successfully opened the key then, it is not localized.
  723. return lResult != ERROR_SUCCESS;
  724. }
  725. // Get the localized Netware Print provider name from nwcfg.dll.
  726. HRESULT GetNWPrintProviderName (LPWSTR *lppPrintProvider)
  727. {
  728. LPWSTR lpszNWCfgDll;
  729. int iLen;
  730. HMODULE hModule;
  731. WCHAR lpszNWCName[100];
  732. DWORD dwLen;
  733. HRESULT hr;
  734. *lppPrintProvider = NULL;
  735. dwLen = GetWindowsDirectoryW( NULL, 0 );
  736. if ( dwLen == 0 )
  737. {
  738. return HRESULT_FROM_WIN32(GetLastError());
  739. }
  740. lpszNWCfgDll = (LPWSTR)MemAlloc( (dwLen + celems(c_szNWCfgDll) + 2)
  741. * sizeof(WCHAR) );
  742. if ( !lpszNWCfgDll )
  743. {
  744. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  745. }
  746. if ( GetWindowsDirectoryW(lpszNWCfgDll, dwLen) == 0 )
  747. {
  748. hr = HRESULT_FROM_WIN32(GetLastError());
  749. }
  750. else
  751. {
  752. if ( lpszNWCfgDll[dwLen-1] == L'\\' )
  753. {
  754. lstrcatW( lpszNWCfgDll, c_szNWCfgDll );
  755. }
  756. else
  757. {
  758. lstrcatW( lpszNWCfgDll, L"\\" );
  759. lstrcatW( lpszNWCfgDll, c_szNWCfgDll );
  760. }
  761. hModule = LoadLibraryExW( lpszNWCfgDll, NULL, LOAD_LIBRARY_AS_DATAFILE );
  762. if ( hModule )
  763. {
  764. iLen = LoadStringW( hModule, NWC_PRINT_PROVIDER, lpszNWCName, 100 );
  765. if ( iLen > 0 )
  766. {
  767. *lppPrintProvider = (LPWSTR)MemAlloc( (iLen + 1) * sizeof(WCHAR) );
  768. lstrcpyW( *lppPrintProvider, lpszNWCName );
  769. hr = S_OK;
  770. }
  771. else
  772. {
  773. hr = HRESULT_FROM_WIN32( GetLastError() );
  774. }
  775. FreeLibrary( hModule );
  776. }
  777. else
  778. {
  779. hr = HRESULT_FROM_WIN32( GetLastError() );
  780. }
  781. }
  782. MemFree( lpszNWCfgDll );
  783. return hr;
  784. }
  785. #endif