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.

461 lines
14 KiB

  1. /****************************************************************************\
  2. MISCAPI.C / OPK Wizard (OPKWIZ.EXE)
  3. Microsoft Confidential
  4. Copyright (c) Microsoft Corporation 1999
  5. All rights reserved
  6. Misc. API source file for generic APIs used in the OPK Wizard.
  7. 4/99 - Jason Cohen (JCOHEN)
  8. Added this new source file for the OPK Wizard as part of the
  9. Millennium rewrite.
  10. 09/2000 - Stephen Lodwick (STELO)
  11. Ported OPK Wizard to Whistler
  12. \****************************************************************************/
  13. //
  14. // Include file(s)
  15. //
  16. #include "pch.h"
  17. #include "resource.h"
  18. //
  19. // Internal Defined Value(s):
  20. //
  21. #define STR_URLDEF _T("http://")
  22. #define STR_EVENT_CANCEL _T("SETUPMGR_EVENT_CANCEL")
  23. //
  24. // Internal Defined Macro(s):
  25. //
  26. #define MALLOC(cb) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb)
  27. #define FREE(lp) ( (lp != NULL) ? ( (HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, (LPVOID) lp)) ? ((lp = NULL) == NULL) : (FALSE) ) : (FALSE) )
  28. //
  29. // Internal Type Definition(s):
  30. //
  31. typedef struct _COPYDIRDATA
  32. {
  33. HWND hwndParent;
  34. LPTSTR lpSrc;
  35. LPTSTR lpDst;
  36. HANDLE hEvent;
  37. } COPYDIRDATA, *PCOPYDIRDATA, *LPCOPYDIRDATA;
  38. //
  39. // Internal Function Prototype(s):
  40. //
  41. LRESULT CALLBACK CopyDirDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  42. DWORD WINAPI CopyDirThread(LPVOID lpVoid);
  43. //
  44. // External Function(s):
  45. //
  46. // If we find a key name with _Gray then *pfGray == TRUE
  47. //
  48. void ReadInstallInsKey(TCHAR szSection[], TCHAR szKey[], TCHAR szValue[], INT cchValue, TCHAR szIniFile[], BOOL* pfGray)
  49. {
  50. TCHAR szTempKey[MAX_PATH];
  51. HRESULT hrCat;
  52. if (!pfGray)
  53. return;
  54. lstrcpyn(szTempKey, szKey, AS(szTempKey));
  55. if (!OpkGetPrivateProfileString(szSection, szTempKey, szValue, szValue, cchValue, szIniFile)) {
  56. hrCat=StringCchCat(szTempKey, AS(szTempKey), GRAY);
  57. if (OpkGetPrivateProfileString(szSection, szTempKey, szValue, szValue, cchValue, szIniFile))
  58. *pfGray = TRUE;
  59. else
  60. *pfGray = TRUE; // default to unchecked if not found!
  61. }
  62. else
  63. *pfGray = FALSE;
  64. }
  65. // If pfGrayed == TRUE then concatenate _Gray to the key name
  66. //
  67. void WriteInstallInsKey(TCHAR szSection[], TCHAR szKey[], TCHAR szValue[], TCHAR szIniFile[], BOOL fGrayed)
  68. {
  69. TCHAR szKeyTemp[MAX_PATH];
  70. HRESULT hrCat;
  71. // Clear the old value
  72. //
  73. lstrcpyn(szKeyTemp, szKey, AS(szKeyTemp));
  74. OpkWritePrivateProfileString(szSection, szKeyTemp, NULL, szIniFile);
  75. hrCat=StringCchCat(szKeyTemp, AS(szKeyTemp), GRAY);
  76. OpkWritePrivateProfileString(szSection, szKeyTemp, NULL, szIniFile);
  77. // Write the new value
  78. lstrcpyn(szKeyTemp, szKey, AS(szKeyTemp));
  79. if (fGrayed)
  80. hrCat=StringCchCat(szKeyTemp, AS(szKeyTemp), GRAY);
  81. OpkWritePrivateProfileString(szSection, szKeyTemp, szValue, szIniFile);
  82. }
  83. // NOTE: pszFileName must point to buffer at least length MAX_PATH
  84. void CheckValidBrowseFolder(TCHAR* pszFileName)
  85. {
  86. if (NULL == pszFileName)
  87. return;
  88. // Last known good browse start folder
  89. //
  90. PathRemoveFileSpec(pszFileName);
  91. if (!lstrlen(pszFileName))
  92. lstrcpyn(pszFileName, g_App.szLastKnownBrowseFolder, MAX_PATH);
  93. }
  94. void SetLastKnownBrowseFolder(TCHAR* pszFileName)
  95. {
  96. if (NULL == pszFileName)
  97. return;
  98. // Save Last known good browse start folder
  99. //
  100. PathCombine(g_App.szLastKnownBrowseFolder, pszFileName, NULL);
  101. PathRemoveFileSpec(g_App.szLastKnownBrowseFolder);
  102. }
  103. // NOTE: lpszURL is assumed to point to a buffer at least MAX_URL in length
  104. BOOL ValidURL(LPTSTR lpszURL)
  105. {
  106. BOOL bResult = TRUE;
  107. TCHAR szBuffer[MAX_PATH] = NULLSTR;
  108. HRESULT hrCat;
  109. // Check if valid URL
  110. //
  111. if ( !PathIsURL(lpszURL) )
  112. {
  113. // Check if empty string first
  114. //
  115. if (0 == lstrlen(lpszURL))
  116. bResult = FALSE;
  117. else {
  118. // Currently not a valid URL, we are now going to prepend the
  119. // URL with http:// and then test the validity again
  120. //
  121. lstrcpyn(szBuffer, STR_URLDEF, AS(szBuffer));
  122. hrCat=StringCchCat(szBuffer, AS(szBuffer), lpszURL);
  123. // Still not a valid URL or we were unable to copy the string
  124. //
  125. if ( !PathIsURL(szBuffer) ||
  126. !lstrcpyn(lpszURL, szBuffer, MAX_URL) )
  127. bResult = FALSE;
  128. }
  129. }
  130. return bResult;
  131. }
  132. BOOL IsFolderShared(LPWSTR lpFolder, LPWSTR lpShare, DWORD cbShare)
  133. {
  134. LPSHARE_INFO_502 lpsi502 = NULL;
  135. DWORD dwRead = 0,
  136. dwTotal = 0;
  137. NET_API_STATUS nas;
  138. BOOL bRet = FALSE,
  139. bBest = FALSE,
  140. bBuffer = ( lpShare && cbShare );
  141. PACL paclOld = NULL;
  142. TCHAR szUnc[MAX_COMPUTERNAME_LENGTH + 4] = NULLSTR;
  143. // Success or failure, we will always atleast pass back the computer
  144. // name if they passed in a buffer. So here is where we create the
  145. // computer name part of the path.
  146. //
  147. if ( bBuffer )
  148. {
  149. DWORD cbUnc = AS(szUnc) - 2;
  150. HRESULT hrCat;
  151. // We want to return the UNC path, so first need the \\ plus the
  152. // computer name.
  153. //
  154. // NOTE: We hard coded the length of the "\\" string below as 2
  155. // in two different places. Once just above, and once below
  156. // in the GetComputerName() call. We also hard code the "\"
  157. // string below as 1 when adding to the lenght of the string
  158. // after adding the computer name. So don't forget these things
  159. // if you make some changes here.
  160. //
  161. lstrcpyn(szUnc, _T("\\\\"), cbUnc);
  162. if ( ( GetComputerName(szUnc + 2, &cbUnc) ) &&
  163. ( AS(szUnc) > ((DWORD) lstrlen(szUnc) + 1) ) )
  164. {
  165. // Added on a backslash so we can add the share name.
  166. //
  167. hrCat=StringCchCat(szUnc,AS(szUnc), _T("\\"));
  168. }
  169. else
  170. {
  171. // If GetComputerName() fails, that is bad. But we will just
  172. // return the share name. That is about all we can do.
  173. //
  174. szUnc[0] = NULLCHR;
  175. }
  176. }
  177. // Now share time, first retrieve all the shares on this machine.
  178. //
  179. nas = NetShareEnum(NULL, 502, (unsigned char **) &lpsi502, MAX_PREFERRED_LENGTH, &dwRead, &dwTotal, NULL);
  180. // Make sure we got a list of shares, otherwise there is nothing.
  181. // we can do. Because we specify MAX_PREFERRED_LENGTH, we should
  182. // never get ERROR_MORE_DATA, but if for some reason we do there is
  183. // no reason not to loop through the ones we did get.
  184. //
  185. if ( ( lpsi502 ) &&
  186. ( ( nas == NERR_Success ) || ( nas == ERROR_MORE_DATA ) ) )
  187. {
  188. int iLength = lstrlen(lpFolder);
  189. LPTSTR lpSearch = lpFolder + iLength;
  190. HRESULT hrCat;
  191. // Trailing backslash is only bad if not the root folder.
  192. //
  193. if ( iLength > 3 )
  194. {
  195. // See if the folder has a trailing backslash.
  196. //
  197. lpSearch = CharPrev(lpFolder, lpSearch);
  198. if ( *lpSearch == _T('\\') )
  199. {
  200. iLength--;
  201. }
  202. }
  203. // Go through all the shares until we fine the best
  204. // one for this directory.
  205. //
  206. while ( dwRead-- && !bBest )
  207. {
  208. // See if this share is a disk share and is the
  209. // same path passed in.
  210. //
  211. if ( ( lpsi502[dwRead].shi502_type == STYPE_DISKTREE ) &&
  212. ( StrCmpNI(lpsi502[dwRead].shi502_path, lpFolder, iLength) == 0 ) &&
  213. ( lstrlen(lpsi502[dwRead].shi502_path) == iLength ) )
  214. {
  215. // If this directory is shared more than once, we want to use
  216. // the first one we fine with no security descriptor, because
  217. // then it is most likely shared out to everyone.
  218. //
  219. if ( lpsi502[dwRead].shi502_security_descriptor == NULL )
  220. {
  221. // If there is no security descriptor, then everyone should have
  222. // access and this is a good share.
  223. //
  224. bBest = TRUE;
  225. }
  226. // If we have no ACL, or we reset it because the new one is better,
  227. // then we want to copy off the share name into our return buffer.
  228. //
  229. if ( !bRet || bBest )
  230. {
  231. // Return the share name for this directory in the supplied buffer
  232. // (if the buffer is NULL or zero size, we just return TRUE so they
  233. // know that the folder is shared even if they don't care what the
  234. // name of the share is).
  235. //
  236. if ( bBuffer )
  237. {
  238. // Find out what we have room for in the return buffer.
  239. //
  240. if ( cbShare > (DWORD) (lstrlen(lpsi502[dwRead].shi502_netname) + lstrlen(szUnc)) )
  241. {
  242. // Copy the computer name and share into return buffer.
  243. //
  244. lstrcpyn(lpShare, szUnc, cbShare);
  245. hrCat=StringCchCat(lpShare, cbShare, lpsi502[dwRead].shi502_netname);
  246. }
  247. else if ( cbShare > (DWORD) lstrlen(lpsi502[dwRead].shi502_netname) )
  248. {
  249. // Return buffer not big enough for both computer name and
  250. // share name, so just return the share name.
  251. //
  252. lstrcpyn(lpShare, lpsi502[dwRead].shi502_netname,cbShare);
  253. }
  254. else
  255. {
  256. // Not big enough for both, so return TRUE because we found a
  257. // share, but don't return anything in the buffer.
  258. //
  259. *lpShare = NULLCHR;
  260. }
  261. }
  262. }
  263. // We found one, so always set this to TRUE.
  264. //
  265. bRet = TRUE;
  266. }
  267. }
  268. }
  269. // Make sure and free the buffer returned by NetShareEnum().
  270. //
  271. if ( lpsi502 )
  272. NetApiBufferFree(lpsi502);
  273. // Now check to see if we didn't find the share, because we can
  274. // still just return the computer name.
  275. //
  276. if ( ( !bRet && bBuffer ) &&
  277. ( cbShare > (DWORD) lstrlen(szUnc) ) )
  278. {
  279. lstrcpyn(lpShare, szUnc, cbShare);
  280. }
  281. return bRet;
  282. }
  283. BOOL CopyDirectoryDialog(HINSTANCE hInstance, HWND hwnd, LPTSTR lpSrc, LPTSTR lpDst)
  284. {
  285. COPYDIRDATA cdd;
  286. // Pass in via the structure the source and destination the dialog needs
  287. // to know about.
  288. //
  289. cdd.lpSrc = lpSrc;
  290. cdd.lpDst = lpDst;
  291. // Create the progress dialog.
  292. //
  293. return ( DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PROGRESS), hwnd, CopyDirDlgProc, (LPARAM) &cdd) != 0 );
  294. }
  295. BOOL CopyResetFileErr(HWND hwnd, LPCTSTR lpSource, LPCTSTR lpTarget)
  296. {
  297. BOOL bReturn;
  298. if ( !(bReturn = CopyResetFile(lpSource, lpTarget)) && hwnd )
  299. MsgBox(hwnd, IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, lpSource);
  300. return bReturn;
  301. }
  302. //
  303. // Internal Function(s):
  304. //
  305. LRESULT CALLBACK CopyDirDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  306. {
  307. static LPCOPYDIRDATA lpcdd = NULL;
  308. switch (uMsg)
  309. {
  310. case WM_INITDIALOG:
  311. // Make sure we have out copy directory data structure.
  312. //
  313. if ( lParam )
  314. {
  315. HANDLE hThread;
  316. DWORD dwThreadId;
  317. // Save off our lParam.
  318. //
  319. lpcdd = (LPCOPYDIRDATA) lParam;
  320. // Replace the old parent with the new progress dialog parent.
  321. //
  322. lpcdd->hwndParent = hwnd;
  323. // Need to pass in the cancel event as well.
  324. //
  325. lpcdd->hEvent = CreateEvent(NULL, TRUE, FALSE, STR_EVENT_CANCEL);
  326. // Now create the thread that will copy the actual files.
  327. //
  328. if ( hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CopyDirThread, (LPVOID) lpcdd, 0, &dwThreadId) )
  329. CloseHandle(hThread);
  330. else
  331. EndDialog(hwnd, 0);
  332. }
  333. else
  334. EndDialog(hwnd, 0);
  335. return FALSE;
  336. case WM_COMMAND:
  337. case WM_CLOSE:
  338. // If we have an event, signal it, or just end the dialog.
  339. //
  340. if ( lpcdd && lpcdd->hEvent )
  341. SetEvent(lpcdd->hEvent);
  342. else
  343. EndDialog(hwnd, 0);
  344. return FALSE;
  345. case WM_DESTROY:
  346. // If there is an event, get rid of it.
  347. //
  348. if ( lpcdd && lpcdd->hEvent )
  349. {
  350. CloseHandle(lpcdd->hEvent);
  351. lpcdd->hEvent = NULL;
  352. }
  353. return FALSE;
  354. default:
  355. return FALSE;
  356. }
  357. return TRUE;
  358. }
  359. DWORD WINAPI CopyDirThread(LPVOID lpVoid)
  360. {
  361. LPCOPYDIRDATA lpcdd = (LPCOPYDIRDATA) lpVoid;
  362. HWND hwnd = lpcdd->hwndParent,
  363. hwndProgress = GetDlgItem(hwnd, IDC_PROGRESS);
  364. HANDLE hEvent = lpcdd->hEvent;
  365. DWORD dwRet = 0;
  366. LPTSTR lpSrc = lpcdd->lpSrc,
  367. lpDst = lpcdd->lpDst;
  368. // First we need to create the path.
  369. //
  370. if ( CreatePath(lpDst) )
  371. {
  372. // Setup the progress bar.
  373. //
  374. SendMessage(hwndProgress, PBM_SETSTEP, 1, 0L);
  375. SendMessage(hwndProgress, PBM_SETRANGE32, 0, (LPARAM) FileCount(lpSrc));
  376. // Now copy the directory.
  377. //
  378. if ( CopyDirectoryProgressCancel(hwndProgress, hEvent, lpSrc, lpDst) )
  379. dwRet = 1;
  380. }
  381. // Now end the dialog with our error code and return.
  382. //
  383. EndDialog(hwnd, dwRet);
  384. return dwRet;
  385. }