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.

945 lines
27 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. opk.c
  5. Abstract:
  6. Common modules shared by OPK tools. Note: Source Depot requires that we
  7. publish the .h (E:\NT\admin\published\ntsetup) and .lib
  8. (E:\NT\public\internal\admin\lib).
  9. Author:
  10. Brian Ku (briank) 06/20/2000
  11. Revision History:
  12. 7/00 - Jason Cohen (jcohen)
  13. Added in the rest of the common APIs form Millennium (need for lfnbk).
  14. --*/
  15. //
  16. // Include file(s)
  17. //
  18. #include <pch.h>
  19. #include <tchar.h>
  20. #include <shlwapi.h>
  21. //
  22. // External Function(s):
  23. //
  24. LPTSTR AllocateString(HINSTANCE hInstance, UINT uID)
  25. {
  26. // ISSUE-2002/02/26-acosma - This sets a restriction of 256 characters on the buffer.
  27. //
  28. TCHAR szBuffer[256];
  29. LPTSTR lpBuffer = NULL;
  30. // Load the string from the resource and then allocate
  31. // a buffer just big enough for it. Strings can exceed 256 characters.
  32. //
  33. if ( ( LoadString(hInstance, uID, szBuffer, sizeof(szBuffer) / sizeof(TCHAR)) ) &&
  34. ( lpBuffer = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szBuffer) + 1)) ) )
  35. {
  36. lstrcpy(lpBuffer, szBuffer);
  37. }
  38. // Return the allocated buffer, or NULL if there was an error.
  39. //
  40. return lpBuffer;
  41. }
  42. LPTSTR AllocateExpand(LPTSTR lpszBuffer)
  43. {
  44. LPTSTR lpszExpanded = NULL;
  45. DWORD cbExpanded;
  46. // First we need to get the size of the expanded buffer and
  47. // allocate it.
  48. //
  49. if ( ( cbExpanded = ExpandEnvironmentStrings(lpszBuffer, NULL, 0) ) &&
  50. ( lpszExpanded = (LPTSTR) MALLOC(cbExpanded * sizeof(TCHAR)) ) )
  51. {
  52. // Now expand out the buffer.
  53. //
  54. if ( ( 0 == ExpandEnvironmentStrings(lpszBuffer, lpszExpanded, cbExpanded) ) ||
  55. ( NULLCHR == *lpszExpanded ) )
  56. {
  57. FREE(lpszExpanded);
  58. }
  59. }
  60. // Return the allocated buffer, or NULL if there was an error
  61. // or nothing in the string.
  62. //
  63. return lpszExpanded;
  64. }
  65. LPTSTR AllocateStrRes(HINSTANCE hInstance, LPSTRRES lpsrTable, DWORD cbTable, LPTSTR lpString, LPTSTR * lplpReturn)
  66. {
  67. LPSTRRES lpsrSearch = lpsrTable;
  68. LPTSTR lpReturn = NULL;
  69. BOOL bFound;
  70. // Init this return value.
  71. //
  72. if ( lplpReturn )
  73. *lplpReturn = NULL;
  74. // Try to find the friendly name for this string in our table.
  75. //
  76. while ( ( bFound = ((DWORD) (lpsrSearch - lpsrTable) < cbTable) ) &&
  77. ( lstrcmpi(lpString, lpsrSearch->lpStr) != 0 ) )
  78. {
  79. lpsrSearch++;
  80. }
  81. // If it was found, allocate the friendly name from the resource.
  82. //
  83. if ( bFound )
  84. {
  85. lpReturn = AllocateString(hInstance, lpsrSearch->uId);
  86. if ( lplpReturn )
  87. *lplpReturn = lpsrSearch->lpStr;
  88. }
  89. return lpReturn;
  90. }
  91. int MsgBoxLst(HWND hwndParent, LPTSTR lpFormat, LPTSTR lpCaption, UINT uType, va_list lpArgs)
  92. {
  93. INT nReturn;
  94. DWORD dwCount = 0;
  95. LPTSTR lpText = NULL;
  96. // The format string is required.
  97. //
  98. if ( lpFormat )
  99. {
  100. do
  101. {
  102. // Allocate 1k of characters at a time.
  103. //
  104. dwCount += 1024;
  105. // Free the previous buffer, if there was one.
  106. //
  107. FREE(lpText);
  108. // Allocate a new buffer.
  109. //
  110. if ( lpText = MALLOC(dwCount * sizeof(TCHAR)) )
  111. nReturn = _vsntprintf(lpText, dwCount, lpFormat, lpArgs);
  112. else
  113. nReturn = 0;
  114. }
  115. while ( nReturn < 0 );
  116. // Make sure we have the format string.
  117. //
  118. if ( lpText )
  119. {
  120. // Display the message box.
  121. //
  122. nReturn = MessageBox(hwndParent, lpText, lpCaption, uType);
  123. FREE(lpText);
  124. }
  125. }
  126. else
  127. nReturn = 0;
  128. // Return the return value of the MessageBox() call. If there was a memory
  129. // error, 0 will be returned.
  130. //
  131. return nReturn;
  132. }
  133. int MsgBoxStr(HWND hwndParent, LPTSTR lpFormat, LPTSTR lpCaption, UINT uType, ...)
  134. {
  135. va_list lpArgs;
  136. // Initialize the lpArgs parameter with va_start().
  137. //
  138. va_start(lpArgs, uType);
  139. // Return the return value of the MessageBox() call. If there was a memory
  140. // error, 0 will be returned. This is all
  141. //
  142. return MsgBoxLst(hwndParent, lpFormat, lpCaption, uType, lpArgs);
  143. }
  144. int MsgBox(HWND hwndParent, UINT uFormat, UINT uCaption, UINT uType, ...)
  145. {
  146. va_list lpArgs;
  147. INT nReturn;
  148. LPTSTR lpFormat = NULL,
  149. lpCaption = NULL;
  150. // Initialize the lpArgs parameter with va_start().
  151. //
  152. va_start(lpArgs, uType);
  153. // Get the format and caption strings from the resource.
  154. //
  155. if ( uFormat )
  156. lpFormat = AllocateString(NULL, uFormat);
  157. if ( uCaption )
  158. lpCaption = AllocateString(NULL, uCaption);
  159. // Return the return value of the MessageBox() call. If there was a memory
  160. // error, 0 will be returned.
  161. //
  162. nReturn = MsgBoxLst(hwndParent, lpFormat, lpCaption, uType, lpArgs);
  163. // Free the format and caption strings.
  164. //
  165. FREE(lpFormat);
  166. FREE(lpCaption);
  167. // Return the value saved from the previous function call.
  168. //
  169. return nReturn;
  170. }
  171. void CenterDialog(HWND hwnd)
  172. {
  173. CenterDialogEx(NULL, hwnd);
  174. }
  175. void CenterDialogEx(HWND hParent, HWND hChild)
  176. {
  177. RECT rcChild,
  178. rcParent;
  179. if ( GetWindowRect(hChild, &rcChild) )
  180. {
  181. // If parent is specified center with respect to parent.
  182. if ( hParent && (GetWindowRect(hParent, &rcParent)) )
  183. SetWindowPos(hChild, NULL, ((rcParent.right + rcParent.left - (rcChild.right - rcChild.left)) / 2), ((rcParent.bottom + rcParent.top - (rcChild.bottom - rcChild.top)) / 2), 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  184. // Otherwise center with respect to screen.
  185. //
  186. else
  187. SetWindowPos(hChild, NULL, ((GetSystemMetrics(SM_CXSCREEN) - (rcChild.right - rcChild.left)) / 2), ((GetSystemMetrics(SM_CYSCREEN) - (rcChild.bottom - rcChild.top)) / 2), 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  188. }
  189. }
  190. INT_PTR CALLBACK SimpleDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  191. {
  192. switch (uMsg)
  193. {
  194. case WM_INITDIALOG:
  195. //CenterDialog(hwnd);
  196. return FALSE;
  197. case WM_COMMAND:
  198. EndDialog(hwnd, LOWORD(wParam));
  199. return FALSE;
  200. default:
  201. return FALSE;
  202. }
  203. return TRUE;
  204. }
  205. INT_PTR SimpleDialogBox(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent)
  206. {
  207. return DialogBox(hInstance, lpTemplate, hWndParent, SimpleDialogProc);
  208. }
  209. /****************************************************************************\
  210. HFONT // Returns a valid handle to a font if it is
  211. // successfully created, or NULL if something
  212. // failed. The font handle should be deleteted
  213. // with DeleteObject() when it is no longer
  214. // needed.
  215. GetFont( // This function creates a font based in the info
  216. // passed in.
  217. HWND hwndCtrl, // Handle to a control that is used for the
  218. // default font characteristics. This may be
  219. // NULL if not default is control is available.
  220. LPTSTR lpFontName, // Points to a string that contains the name of
  221. // the font to create. This parameter may be NULL
  222. // if a valid control handle is passed in. In
  223. // that case, the font of the control is used.
  224. DWORD dwFontSize, // Point size to use for the font. If it is zero,
  225. // the default is used.
  226. BOOL bSymbol // If this is TRUE, the font is set to
  227. // SYMBOL_CHARSET. Typically this is FALSE.
  228. );
  229. \****************************************************************************/
  230. HFONT GetFont(HWND hwndCtrl, LPTSTR lpFontName, DWORD dwFontSize, LONG lFontWeight, BOOL bSymbol)
  231. {
  232. HFONT hFont;
  233. LOGFONT lFont;
  234. BOOL bGetFont;
  235. // If the font name is passed in, then try to use that
  236. // first before getting the font of the control.
  237. //
  238. if ( lpFontName && *lpFontName )
  239. {
  240. // Make sure the font name is not longer than
  241. // 32 characters (including the NULL terminator).
  242. //
  243. if ( lstrlen(lpFontName) >= sizeof(lFont.lfFaceName) )
  244. return NULL;
  245. // Setup the structure to use to get the
  246. // font we want.
  247. //
  248. ZeroMemory(&lFont, sizeof(LOGFONT));
  249. lFont.lfCharSet = DEFAULT_CHARSET;
  250. lstrcpy(lFont.lfFaceName, lpFontName);
  251. }
  252. // First try to get the font that we wanted.
  253. //
  254. if ( ( lpFontName == NULL ) ||
  255. ( *lpFontName == NULLCHR ) ||
  256. ( (hFont = CreateFontIndirect((LPLOGFONT) &lFont)) == NULL ) )
  257. {
  258. // Couldn't get the font we wanted, try the font of the control
  259. // if a valid window handle was passed in.
  260. //
  261. if ( ( hwndCtrl == NULL ) ||
  262. ( (hFont = (HFONT) (WORD) SendMessage(hwndCtrl, WM_GETFONT, 0, 0L)) == NULL ) )
  263. {
  264. // All atempts to get the font failed. We must return NULL.
  265. //
  266. return NULL;
  267. }
  268. }
  269. // Return the font we have now if we don't need to
  270. // change the size or weight.
  271. //
  272. if ( (lFontWeight == 0) && (dwFontSize == 0) )
  273. return hFont;
  274. // We must have a valid HFONT now. Fill in the structure
  275. // and setup the size and weight we wanted for it.
  276. //
  277. bGetFont = GetObject(hFont, sizeof(LOGFONT), (LPVOID) &lFont);
  278. DeleteObject(hFont);
  279. if ( bGetFont )
  280. {
  281. // Set the bold and point size of the font.
  282. //
  283. if ( lFontWeight )
  284. lFont.lfWeight = lFontWeight;
  285. if ( dwFontSize )
  286. lFont.lfHeight = -MulDiv(dwFontSize, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
  287. if ( bSymbol )
  288. lFont.lfCharSet = SYMBOL_CHARSET;
  289. // Create the font.
  290. //
  291. hFont = CreateFontIndirect((LPLOGFONT) &lFont);
  292. }
  293. else
  294. hFont = NULL;
  295. return hFont;
  296. }
  297. void ShowEnableWindow(HWND hwnd, BOOL bShowEnable)
  298. {
  299. EnableWindow(hwnd, bShowEnable);
  300. ShowWindow(hwnd, bShowEnable ? SW_SHOW : SW_HIDE);
  301. }
  302. /****************************************************************************\
  303. BOOL // Returns TRUE if we are running a server OS.
  304. IsServer( // This routine checks if we're running on a
  305. // Server OS.
  306. VOID
  307. );
  308. \****************************************************************************/
  309. BOOL IsServer(VOID)
  310. {
  311. OSVERSIONINFOEX verInfo;
  312. BOOL fReturn = FALSE;
  313. verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  314. if ( ( GetVersionEx((LPOSVERSIONINFO) &verInfo) ) &&
  315. ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) &&
  316. ( ( verInfo.wProductType == VER_NT_SERVER ) ||
  317. ( verInfo.wProductType == VER_NT_DOMAIN_CONTROLLER ) ) )
  318. {
  319. fReturn = TRUE;
  320. }
  321. return fReturn;
  322. }
  323. BOOL IsIA64()
  324. /*++
  325. ===============================================================================
  326. Routine Description:
  327. This routine checks if we're running on a 64-bit machine.
  328. Arguments:
  329. None -
  330. Return Value:
  331. TRUE - We are running on 64-bit machine.
  332. FALSE - Not a 64-bit machine.
  333. ===============================================================================
  334. --*/
  335. {
  336. BOOL fReturn = FALSE;
  337. ULONG_PTR Wow64Info = 0;
  338. DWORD dwSt = 0;
  339. SYSTEM_INFO siSystemInfo;
  340. ZeroMemory( &siSystemInfo, sizeof(SYSTEM_INFO) );
  341. GetSystemInfo(&siSystemInfo);
  342. if ( (siSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
  343. (siSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) )
  344. fReturn = TRUE;
  345. if (!fReturn)
  346. {
  347. // Now make sure that GetSystemInfo isn't lying because we are in emulation mode.
  348. dwSt = NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &Wow64Info, sizeof(Wow64Info), NULL);
  349. if (!NT_SUCCESS(dwSt))
  350. {
  351. // Handle to process is bad, or the code is compiled 32-bit and running on NT4 or earlier.
  352. // Do nothing
  353. }
  354. else if (Wow64Info)
  355. {
  356. // The process is 32-bit and is running inside WOW64.
  357. // We are really on IA64 and running in 32-bit mode.
  358. fReturn = TRUE;
  359. }
  360. }
  361. return fReturn;
  362. }
  363. BOOL ValidDosName(LPCTSTR lpName)
  364. {
  365. LPCTSTR lpSearch = lpName;
  366. int nDot = 0,
  367. nSpot = 0,
  368. nLen;
  369. // Do the easy checks.
  370. //
  371. if ( ( lpSearch == NULL ) ||
  372. ( *lpSearch == NULLCHR ) ||
  373. ( (nLen = lstrlen(lpSearch)) > 12 ) )
  374. {
  375. return FALSE;
  376. }
  377. // Search the string.
  378. //
  379. for (; *lpSearch; lpSearch++)
  380. {
  381. // Check for dots.
  382. //
  383. if ( *lpSearch == _T('.') )
  384. {
  385. // Keep track of the number of dots.
  386. //
  387. nDot++;
  388. nSpot = (int) (lpSearch - lpName);
  389. }
  390. else
  391. {
  392. // Check for valid characters.
  393. //
  394. if ( !( ( ( _T('0') <= *lpSearch ) && ( *lpSearch <= _T('9') ) ) ||
  395. ( ( _T('a') <= *lpSearch ) && ( *lpSearch <= _T('z') ) ) ||
  396. ( ( _T('A') <= *lpSearch ) && ( *lpSearch <= _T('Z') ) ) ||
  397. ( *lpSearch == _T('-') ) ||
  398. ( *lpSearch == _T('_') ) ||
  399. ( *lpSearch == _T('~') ) ) )
  400. {
  401. // Invalid character.
  402. //
  403. return FALSE;
  404. }
  405. }
  406. }
  407. // Make sure the dot is in the right place.
  408. //
  409. if ( ( nDot > 1 ) ||
  410. ( ( nDot == 0 ) && ( nLen > 8 ) ) ||
  411. ( ( nDot == 1 ) && ( nSpot > 8 ) ) ||
  412. ( ( nDot == 1 ) && ( (nLen - nSpot) > 4 ) ) )
  413. {
  414. return FALSE;
  415. }
  416. return TRUE;
  417. }
  418. DWORD GetLineArgs(LPTSTR lpSrc, LPTSTR ** lplplpArgs, LPTSTR * lplpAllArgs)
  419. {
  420. LPTSTR lpCmdLine,
  421. lpArg,
  422. lpDst;
  423. DWORD dwArgs = 0;
  424. BOOL bQuote;
  425. // Fist make sure that we were passed in a valid pointer, we have a command
  426. // line to parse, and that we were able to allocate the memory to hold it.
  427. //
  428. if ( ( lplplpArgs != NULL ) &&
  429. ( lpSrc ) &&
  430. ( *lpSrc ) &&
  431. ( lpCmdLine = (LPTSTR) MALLOC((lstrlen(lpSrc) + 1) * sizeof(TCHAR)) ) )
  432. {
  433. // Fist parse the command line into NULL terminated sub strings.
  434. //
  435. lpDst = lpCmdLine;
  436. while ( *lpSrc )
  437. {
  438. // Eat the preceeding spaces.
  439. //
  440. while ( *lpSrc == _T(' ') )
  441. lpSrc = CharNext(lpSrc);
  442. // Make sure we still have an argument.
  443. //
  444. if ( *lpSrc == _T('\0') )
  445. break;
  446. // Return a pointer to all the command line args if they want one.
  447. //
  448. if ( ( dwArgs == 1 ) && lplpAllArgs )
  449. *lplpAllArgs = lpSrc;
  450. // Save the current arg pointer.
  451. //
  452. lpArg = lpDst;
  453. dwArgs++;
  454. // See if we are looking for the next quote or space.
  455. //
  456. if ( bQuote = (*lpSrc == _T('"')) )
  457. lpSrc = CharNext(lpSrc);
  458. // Copy the argument into our allocated buffer until we
  459. // hit the separating character (which will always be a space).
  460. //
  461. while ( *lpSrc && ( bQuote || ( *lpSrc != _T(' ') ) ) )
  462. {
  463. // We special case the quote.
  464. //
  465. if ( *lpSrc == _T('"') )
  466. {
  467. // If the character before the quote is a backslash, then
  468. // we don't count this as the separating quote.
  469. //
  470. LPTSTR lpPrev = CharPrev(lpCmdLine, lpDst);
  471. if ( lpPrev && ( *lpPrev == _T('\\') ) )
  472. *lpPrev = *lpSrc++;
  473. else
  474. {
  475. // Since we have found the separating quote, set this to
  476. // false so we look for the next space.
  477. //
  478. bQuote = FALSE;
  479. lpSrc++;
  480. }
  481. }
  482. else
  483. *lpDst++ = *lpSrc++;
  484. }
  485. // NULL terminate this argument.
  486. //
  487. *lpDst++ = _T('\0');
  488. }
  489. // Now setup the pointers to each argument. Make sure we have some arguments
  490. // to return and that we have the memory allocated for the array.
  491. //
  492. if ( *lpCmdLine && dwArgs && ( *lplplpArgs = (LPTSTR *) MALLOC(dwArgs * sizeof(LPTSTR)) ) )
  493. {
  494. DWORD dwCount = 0;
  495. // Copy a pointer to each NULL terminated sub string into our
  496. // array of arguments we are going to return.
  497. //
  498. do
  499. {
  500. *(*lplplpArgs + dwCount) = lpCmdLine;
  501. lpCmdLine += lstrlen(lpCmdLine) + 1;
  502. }
  503. while ( ++dwCount < dwArgs );
  504. }
  505. else
  506. {
  507. // Either there were no command line arguments, or the memory allocation
  508. // failed for the list of arguments to return.
  509. //
  510. dwArgs = 0;
  511. FREE(lpCmdLine);
  512. }
  513. }
  514. return dwArgs;
  515. }
  516. DWORD GetCommandLineArgs(LPTSTR ** lplplpArgs)
  517. {
  518. return GetLineArgs(GetCommandLine(), lplplpArgs, NULL);
  519. }
  520. //
  521. // Generic singularly linked list pvItem must be allocated with MALLOC
  522. //
  523. BOOL FAddListItem(PGENERIC_LIST* ppList, PGENERIC_LIST** pppNewItem, PVOID pvItem)
  524. {
  525. if (pppNewItem && *pppNewItem == NULL)
  526. *pppNewItem = ppList;
  527. if (*pppNewItem) {
  528. if (**pppNewItem = (PGENERIC_LIST)MALLOC(sizeof(GENERIC_LIST))) {
  529. (**pppNewItem)->pNext = NULL;
  530. (**pppNewItem)->pvItem = pvItem;
  531. *pppNewItem = &((**pppNewItem)->pNext);
  532. return TRUE;
  533. }
  534. }
  535. return FALSE;
  536. }
  537. void FreeList(PGENERIC_LIST pList)
  538. {
  539. while (pList) {
  540. PGENERIC_LIST pTemp = pList;
  541. pList = pList->pNext;
  542. FREE(pTemp->pvItem);
  543. FREE(pTemp);
  544. }
  545. }
  546. // Find factory.exe from the current process, should be in same directory
  547. //
  548. BOOL FGetFactoryPath(LPTSTR pszFactoryPath)
  549. {
  550. // Attempt to locate FACTORY.EXE
  551. //
  552. // NTRAID#NTBUG9-549770-2002/02/26-acosma,georgeje - Possible buffer overflow.
  553. //
  554. if (pszFactoryPath && GetModuleFileName(NULL, pszFactoryPath, MAX_PATH)) {
  555. if (PathRemoveFileSpec(pszFactoryPath)) {
  556. PathAppend(pszFactoryPath, TEXT("FACTORY.EXE"));
  557. if (FileExists(pszFactoryPath))
  558. return TRUE;
  559. }
  560. }
  561. return FALSE;
  562. }
  563. // Find sysprep.exe from the current process, should be in same directory
  564. //
  565. BOOL FGetSysprepPath(LPTSTR pszSysprepPath)
  566. {
  567. // Attempt to locate SYSPREP.EXE
  568. //
  569. // NTRAID#NTBUG9-549770-2002/02/26-acosma,georgeje - Possible buffer overflow.
  570. //
  571. if (pszSysprepPath && GetModuleFileName(NULL, pszSysprepPath, MAX_PATH)) {
  572. if (PathRemoveFileSpec(pszSysprepPath)) {
  573. PathAppend(pszSysprepPath, TEXT("SYSPREP.EXE"));
  574. if (FileExists(pszSysprepPath))
  575. return TRUE;
  576. }
  577. }
  578. return FALSE;
  579. }
  580. //------------------------------------------------------------------------------------------------------
  581. //
  582. // Function: ConnectNetworkResource
  583. //
  584. // Purpose: This function allows the user to connect to a network resource with
  585. // supplied credentials.
  586. //
  587. // Arguments: lpszPath: Network Resource that should be shared out
  588. // lpszUsername: Username for credentials, can be in form of domain\username
  589. // lpszPassword: Password to use for credentials
  590. // bState: If set to TRUE we will add the connection, if FALSE we will
  591. // attempt to delete the connection
  592. //
  593. // Returns: BOOL If the NetUse command was successful, TRUE is returned
  594. //
  595. //------------------------------------------------------------------------------------------------------
  596. NET_API_STATUS ConnectNetworkResource(LPTSTR lpszPath, LPTSTR lpszUsername, LPTSTR lpszPassword, BOOL bState)
  597. {
  598. BOOL bRet = FALSE;
  599. USE_INFO_2 ui2;
  600. NET_API_STATUS nerr_NetUse;
  601. TCHAR szDomain[MAX_PATH] = NULLSTR,
  602. szNetUse[MAX_PATH] = NULLSTR;
  603. LPTSTR lpUser,
  604. lpSearch;
  605. // Zero out the user information structure
  606. //
  607. ZeroMemory(&ui2, sizeof(ui2));
  608. // Copy the path into our buffer so we can work with it
  609. //
  610. lstrcpyn(szNetUse, lpszPath, AS(szNetUse));
  611. StrRTrm(szNetUse, CHR_BACKSLASH);
  612. if ( szNetUse[0] && PathIsUNC(szNetUse) )
  613. {
  614. // Disconnect from existing share
  615. //
  616. nerr_NetUse = NetUseDel(NULL, szNetUse, USE_NOFORCE);
  617. // We need to Add a connection
  618. //
  619. if ( bState )
  620. {
  621. ui2.ui2_remote = szNetUse;
  622. ui2.ui2_asg_type = USE_DISKDEV;
  623. ui2.ui2_password = lpszPassword;
  624. lstrcpyn(szDomain, lpszUsername, AS(szDomain));
  625. // Break up the Domain\Username for the NetUse function
  626. //
  627. if (lpUser = StrChr(szDomain, CHR_BACKSLASH) )
  628. {
  629. // Put a NULL character after the domain part of the user name
  630. // and advance the pointer to point to the actual user name.
  631. //
  632. *(lpUser++) = NULLCHR;
  633. }
  634. else
  635. {
  636. // Use the computer name in the path as the domain name.
  637. //
  638. if ( lpSearch = StrChr(szNetUse + 2, CHR_BACKSLASH) )
  639. lstrcpyn(szDomain, szNetUse + 2, (int)((lpSearch - (szNetUse + 2)) + 1));
  640. else
  641. lstrcpyn(szDomain, szNetUse + 2, AS(szDomain));
  642. lpUser = lpszUsername;
  643. }
  644. // Set the domain and user name pointers into our struct.
  645. //
  646. ui2.ui2_domainname = szDomain;
  647. ui2.ui2_username = lpUser;
  648. // Create a connect to the share
  649. //
  650. nerr_NetUse = NetUseAdd(NULL, 2, (LPBYTE) &ui2, NULL);
  651. }
  652. }
  653. else
  654. nerr_NetUse = NERR_UseNotFound;
  655. // Return failure/success
  656. //
  657. return nerr_NetUse;
  658. }
  659. BOOL GetUncShare(LPCTSTR lpszPath, LPTSTR lpszShare, DWORD cbShare)
  660. {
  661. BOOL bRet;
  662. LPCTSTR lpSrc = lpszPath;
  663. LPTSTR lpDst = lpszShare;
  664. DWORD dwBackslashes,
  665. dwCount;
  666. // Make sure the path is a UNC by calling the shell function.
  667. //
  668. bRet = PathIsUNC(lpszPath);
  669. // This will loop through the path string twice, each time coping all the
  670. // backslashes and then all the non-backslashes. So if the string passed
  671. // in was "\\COMPUTER\SHARE\DIR\FILE.NAME", the first pass will copy
  672. // "\\COMPUTER" and the next pass would then copy "\SHARE" so the final
  673. // string would then be "\\COMPUTER\SHARE". This loop also verifies there
  674. // are the correct number of backslashes and non-backslashes. If there is
  675. // no return buffer, then we just are verifing the share.
  676. //
  677. for ( dwBackslashes = 2; dwBackslashes && bRet; dwBackslashes-- )
  678. {
  679. // First copy the backslashes.
  680. //
  681. dwCount = 0;
  682. while ( _T('\\') == *lpSrc )
  683. {
  684. if ( lpDst && cbShare )
  685. {
  686. *lpDst++ = *lpSrc;
  687. cbShare--;
  688. }
  689. lpSrc++;
  690. dwCount++;
  691. }
  692. // Make sure the number of backslashes is correct.
  693. // The fist pass there should be two and the next
  694. // pass should be just one.
  695. //
  696. if ( dwBackslashes != dwCount )
  697. {
  698. bRet = FALSE;
  699. }
  700. else
  701. {
  702. // Now copy the non-backslashes.
  703. //
  704. dwCount = 0;
  705. while ( ( *lpSrc ) &&
  706. ( _T('\\') != *lpSrc ) )
  707. {
  708. if ( lpDst && cbShare )
  709. {
  710. *lpDst++ = *lpSrc;
  711. cbShare--;
  712. }
  713. lpSrc++;
  714. dwCount++;
  715. }
  716. // Make sure there was at least one non-backslash.
  717. // character.
  718. //
  719. // Also if we are on the first pass and the path
  720. // buffer is already empty, then we don't have the
  721. // share part so just error out.
  722. //
  723. if ( ( 0 == dwCount ) ||
  724. ( ( 2 == dwBackslashes ) &&
  725. ( NULLCHR == *lpSrc ) ) )
  726. {
  727. bRet = FALSE;
  728. }
  729. }
  730. }
  731. // Only fix up the return buffer if there is one.
  732. //
  733. if ( lpszShare )
  734. {
  735. // Make sure that we didn't fail and that we still
  736. // have room for the null terminator.
  737. //
  738. if ( bRet && cbShare )
  739. {
  740. // Don't forget to null terminate the return string.
  741. //
  742. *lpDst = NULLCHR;
  743. }
  744. else
  745. {
  746. // If we failed or ran out of buffer room, make sure
  747. // we don't return anything.
  748. //
  749. *lpszShare = NULLCHR;
  750. }
  751. }
  752. return bRet;
  753. }
  754. DWORD GetSkuType()
  755. {
  756. DWORD dwRet = 0;
  757. OSVERSIONINFOEX osvi;
  758. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  759. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  760. if ( GetVersionEx((LPOSVERSIONINFO) &osvi) )
  761. {
  762. if ( VER_NT_WORKSTATION == osvi.wProductType )
  763. {
  764. if ( GET_FLAG(osvi.wSuiteMask, VER_SUITE_PERSONAL) )
  765. {
  766. dwRet = VER_SUITE_PERSONAL;
  767. }
  768. else
  769. {
  770. dwRet = VER_NT_WORKSTATION;
  771. }
  772. }
  773. else
  774. {
  775. if ( GET_FLAG(osvi.wSuiteMask, VER_SUITE_DATACENTER) )
  776. {
  777. dwRet = VER_SUITE_DATACENTER;
  778. }
  779. else if ( GET_FLAG(osvi.wSuiteMask, VER_SUITE_ENTERPRISE) )
  780. {
  781. dwRet = VER_SUITE_ENTERPRISE;
  782. }
  783. else if ( GET_FLAG(osvi.wSuiteMask, VER_SUITE_BLADE) )
  784. {
  785. dwRet = VER_SUITE_BLADE;
  786. }
  787. else
  788. {
  789. dwRet = VER_NT_SERVER;
  790. }
  791. }
  792. }
  793. return dwRet;
  794. }