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.

965 lines
26 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 1999
  4. Module Name:
  5. utils.cpp
  6. Abstract:
  7. Author:
  8. Rahul Thombre (RahulTh) 4/30/1998
  9. Revision History:
  10. 4/30/1998 RahulTh
  11. Created this module.
  12. 10/12/98 RahulTh
  13. Better error handling capabilities added : CError etc.
  14. --*/
  15. #include "precomp.hxx"
  16. #include <irmonftp.h>
  17. LONG g_lLinkOnDesktop = 0;
  18. //the path of the desktop folder.
  19. TCHAR g_lpszDesktopFolder[MAX_PATH];
  20. //the path to the send to folder;
  21. TCHAR g_lpszSendToFolder[MAX_PATH];
  22. BOOL GetShortcutInfo (
  23. LPTSTR lpszShortcutName,
  24. ULONG ShortCutNameLength,
  25. LPTSTR lpszFullExeName,
  26. ULONG ExeNameLength
  27. );
  28. BOOL GetSendToInfo (
  29. LPTSTR lpszSendToName,
  30. ULONG SendToNameLength,
  31. LPTSTR lpszFullExeName,
  32. ULONG FullExeNameLength
  33. );
  34. #define VALIDATE_SEND_COOKIE(cookie) \
  35. { \
  36. __try \
  37. { \
  38. *pStatus = ERROR_INVALID_DATA; \
  39. if (MAGIC_ID != ((CSendProgress *)cookie)->m_dwMagicID) \
  40. return; \
  41. *pStatus = ERROR_SUCCESS; \
  42. } \
  43. __except (EXCEPTION_EXECUTE_HANDLER) \
  44. { \
  45. return; \
  46. } \
  47. }
  48. //
  49. // wireless link specific errors
  50. //
  51. ERROR_TO_STRING_ID g_ErrorToStringId[] =
  52. {
  53. {ERROR_IRTRANP_OUT_OF_MEMORY, IDS_ERROR_NO_MEMORY},
  54. {ERROR_IRTRANP_DISK_FULL, IDS_ERROR_DISK_FULL},
  55. {ERROR_SCEP_CANT_CREATE_FILE, IDS_ERROR_DISK_FULL},
  56. {ERROR_SCEP_ABORT, IDS_ERROR_ABORTED},
  57. {ERROR_SCEP_INVALID_PROTOCOL, IDS_ERROR_PROTOCOL},
  58. {ERROR_SCEP_PDU_TOO_LARGE, IDS_ERROR_PROTOCOL},
  59. {ERROR_BFTP_INVALID_PROTOCOL, IDS_ERROR_PROTOCOL},
  60. {ERROR_BFTP_NO_MORE_FRAGMENTS, IDS_ERROR_PROTOCOL},
  61. {ERROR_SUCCESS, -1}
  62. };
  63. ////////////////////////////////////////////////////////////////////
  64. //
  65. //Miscellaneous useful functions
  66. //
  67. ///////////////////////////////////////////////////////////////////
  68. int ParseFileNames (TCHAR* pszInString, TCHAR* pszFilesList, int& iCharCount)
  69. {
  70. ASSERT(pszFilesList != NULL);
  71. ASSERT(pszInString != NULL);
  72. BOOL fInQuotes = FALSE;
  73. BOOL fIgnoreSpaces = FALSE;
  74. TCHAR* pszSource = pszInString;
  75. TCHAR* pszTarget = pszFilesList;
  76. int iFileCount = 0;
  77. TCHAR curr;
  78. //ignore leading whitespaces
  79. while(' ' == *pszSource || '\t' == *pszSource)
  80. pszSource++;
  81. iCharCount = 0;
  82. *pszTarget = '\0'; //precautionary measures
  83. if ('\0' == *pszSource) //special case : if this was an empty string, return 0
  84. return iFileCount;
  85. //parse the string to get filenames
  86. while(curr = *pszSource)
  87. {
  88. if('\"' == curr)
  89. {
  90. fInQuotes = fInQuotes?FALSE:TRUE;
  91. }
  92. else if(' ' == curr && !fInQuotes)
  93. {
  94. if(!fIgnoreSpaces)
  95. {
  96. *pszTarget++ = 0;
  97. iFileCount++;
  98. iCharCount++;
  99. fIgnoreSpaces = TRUE;
  100. }
  101. }
  102. else
  103. {
  104. *pszTarget++ = curr;
  105. iCharCount++;
  106. fIgnoreSpaces = FALSE;
  107. }
  108. pszSource++;
  109. }
  110. if(' ' != *(pszSource-1)) //if there was no trailing space
  111. {
  112. *pszTarget++ = '\0'; //then the last file was not accounted for.
  113. iCharCount++; //so we do it here
  114. iFileCount++;
  115. }
  116. *pszTarget++ = '\0'; //should have 2 terminating nulls
  117. iCharCount++;
  118. return iFileCount;
  119. }
  120. //+--------------------------------------------------------------------------
  121. //
  122. // Function: GetIRRegVal
  123. //
  124. // Synopsis: gets the specified registry value from the IR subtree in HKCU
  125. //
  126. // Arguments: [in] szValName : the name of the value.
  127. // [in] dwDefVal : the default value to be returned if the read
  128. // from the registry fails or if the value is
  129. // missing.
  130. //
  131. // Returns: the actual value stored in the registry or the default value
  132. // if the read fails.
  133. //
  134. // History: 10/27/1999 RahulTh created
  135. //
  136. // Notes:
  137. //
  138. //---------------------------------------------------------------------------
  139. DWORD GetIRRegVal (LPCTSTR szValName, DWORD dwDefVal)
  140. {
  141. HKEY hftKey = NULL;
  142. DWORD iSize = sizeof(DWORD);
  143. DWORD data = 0;
  144. DWORD Status;
  145. RegOpenKeyEx (HKEY_CURRENT_USER, TEXT("Control Panel\\Infrared\\File Transfer"),
  146. 0, KEY_READ, &hftKey);
  147. if (!hftKey)
  148. return dwDefVal;
  149. Status = RegQueryValueEx (hftKey, szValName, NULL, NULL,
  150. (LPBYTE)&data, &iSize);
  151. if (ERROR_SUCCESS != Status)
  152. data = dwDefVal;
  153. RegCloseKey (hftKey);
  154. return data;
  155. }
  156. TCHAR* GetFullPathnames (TCHAR* pszPath, //directory in which the files are located
  157. const TCHAR* pszFilesList, //NULL separated list of filenames
  158. int iFileCount, //number of files in pszFilesList
  159. int& iCharCount //number of characters in pszFilesList. also returns the number of chars in the return string
  160. )
  161. {
  162. int iChars;
  163. int iPathLen = lstrlen(pszPath);
  164. if (pszPath[iPathLen - 1] != '\\') //append a '\' character to the path if not already present
  165. {
  166. pszPath[iPathLen++] = '\\';
  167. pszPath[iPathLen] = '\0';
  168. }
  169. int iSize = (iChars = iFileCount*iPathLen + iCharCount);
  170. TCHAR* pszFilePathList = new TCHAR[iSize];
  171. TCHAR* pszTemp = pszFilePathList;
  172. int iLen;
  173. while(*pszFilesList)
  174. {
  175. //
  176. // start with the path
  177. //
  178. StringCchCopy(pszTemp, iSize ,pszPath);
  179. //
  180. // add on the file name
  181. //
  182. StringCchCat(pszTemp, iSize, pszFilesList);
  183. //
  184. // move the next files name
  185. //
  186. iLen = lstrlen(pszFilesList);
  187. pszFilesList += iLen + 1;
  188. //
  189. // move past the current path and file name
  190. //
  191. iLen = lstrlen(pszTemp);
  192. pszTemp += iLen + 1;
  193. iSize-=iLen;
  194. }
  195. *pszTemp = '\0'; //should be terminated by 2 null characters
  196. iCharCount = (int)(pszTemp - pszFilePathList) + 1; //return the actual char count of this string
  197. return pszFilePathList;
  198. }
  199. TCHAR* ProcessOneFile (TCHAR* pszPath, //directory in which the files are located
  200. const TCHAR* pszFilesList, //NULL separated list of filenames
  201. int iFileCount, //number of files in pszFilesList
  202. int& iCharCount //number of characters in pszFilesList. also returns the number of characters in the return string
  203. )
  204. {
  205. int iFileLen, iPathLen;
  206. TCHAR* pszFullFileName;
  207. iFileLen = lstrlen (pszFilesList);
  208. iPathLen = lstrlen (pszPath);
  209. ASSERT (iFileLen);
  210. ASSERT (iPathLen);
  211. if(':' == pszFilesList[1] //this is an absolute path starting with the drive letter;
  212. || ('\\' == pszFilesList[0] && '\\' == pszFilesList[1]) //UNC path
  213. )
  214. {
  215. pszFullFileName = new TCHAR [iFileLen + 2];
  216. StringCchCopy(pszFullFileName, iFileLen + 2, pszFilesList);
  217. pszFullFileName[iFileLen + 1] = '\0'; //we need to have 2 terminating nulls
  218. iCharCount = iFileLen + 2;
  219. }
  220. else if('\\' == pszFilesList[0]) //path relative to the root
  221. {
  222. iCharCount = iFileLen + 2 /*drive letter and colon*/ + 2 /*terminating nulls*/;
  223. pszFullFileName = new TCHAR [iCharCount];
  224. pszFullFileName[0] = pszPath[0];
  225. pszFullFileName[1] = pszPath[1];
  226. StringCchCopy(pszFullFileName + 2, iCharCount-2, pszFilesList);
  227. pszFullFileName[iCharCount - 1] = '\0'; //we need to have 2 terminating nulls
  228. }
  229. else //ordinary file name
  230. {
  231. iCharCount = iPathLen + iFileLen + 2; //2 terminating nulls
  232. //
  233. // sometimes the path does not have a \ at the end, so we need to add these ourselves
  234. //
  235. iCharCount += ('\\' == pszPath[iPathLen - 1])?0:1;
  236. pszFullFileName = new TCHAR [iCharCount];
  237. //
  238. // put in the path
  239. //
  240. StringCchCopy(pszFullFileName,iCharCount, pszPath);
  241. if ('\\' != pszPath[iPathLen - 1]) {
  242. //
  243. // we need to add the \ ourselves
  244. //
  245. StringCchCat(pszFullFileName,iCharCount,TEXT("\\"));
  246. }
  247. //
  248. // add on the file name
  249. //
  250. StringCchCat(pszFullFileName,iCharCount,pszFilesList);
  251. pszFullFileName[iCharCount - 1] = '\0'; //2 terminating nulls
  252. }
  253. return pszFullFileName;
  254. }
  255. //+--------------------------------------------------------------------------
  256. //
  257. // Function: GetPrimaryAppWindow
  258. //
  259. // Synopsis: gets the handle to the main window of an existing instance of
  260. // irftp
  261. //
  262. // Arguments: none.
  263. //
  264. // Returns: handle to the window if it finds one. otherwise NULL.
  265. //
  266. // History: 6/30/1999 RahulTh created
  267. //
  268. // Notes:
  269. //
  270. //---------------------------------------------------------------------------
  271. HWND GetPrimaryAppWindow (void)
  272. {
  273. HWND hwnd = NULL;
  274. int i = 1;
  275. //try to find the window for 5 seconds.
  276. do
  277. {
  278. hwnd = FindWindow (L"#32770", //the dialog class
  279. MAIN_WINDOW_TITLE);
  280. if (hwnd)
  281. break;
  282. Sleep (500);
  283. } while ( i++ <= 10 );
  284. return hwnd;
  285. }
  286. ///////////////////////////////////////////////////////////////////////////////////////
  287. // RPC Server functions
  288. //////////////////////////////////////////////////////////////////////////////////////
  289. void _PopupUI (handle_t Binding)
  290. {
  291. int nResponse;
  292. appController->PostMessage(WM_APP_TRIGGER_UI);
  293. return;
  294. }
  295. void _InitiateFileTransfer (handle_t Binding, ULONG lSize, wchar_t __RPC_FAR lpszFilesList[])
  296. {
  297. COPYDATASTRUCT cStruct;
  298. cStruct.dwData = lSize;
  299. cStruct.cbData = lSize * sizeof(wchar_t);
  300. cStruct.lpData = (LPVOID)(lpszFilesList);
  301. appController->SendMessage(WM_COPYDATA, (WPARAM)NULL, (LPARAM)(&cStruct));
  302. }
  303. void _DisplaySettings (handle_t Binding)
  304. {
  305. appController->PostMessage(WM_APP_TRIGGER_SETTINGS);
  306. }
  307. void _UpdateSendProgress (
  308. handle_t RpcBinding,
  309. COOKIE Cookie,
  310. wchar_t CurrentFile[],
  311. __int64 BytesInTransfer,
  312. __int64 BytesTransferred,
  313. error_status_t* pStatus
  314. )
  315. {
  316. VALIDATE_SEND_COOKIE (Cookie)
  317. CSendProgress* progressDlg = (CSendProgress*)Cookie;
  318. int percentComplete;
  319. if (BytesInTransfer)
  320. {
  321. percentComplete = (int)((BytesTransferred*100.0)/BytesInTransfer);
  322. }
  323. else
  324. {
  325. percentComplete = 100;
  326. }
  327. progressDlg->PostMessage(WM_APP_UPDATE_PROGRESS, (WPARAM) 0, (LPARAM) percentComplete);
  328. if (100 > percentComplete)
  329. {
  330. progressDlg->SetCurrentFileName (CurrentFile);
  331. }
  332. *pStatus = 0;
  333. }
  334. void _OneSendFileFailed(
  335. handle_t RpcBinding,
  336. COOKIE Cookie,
  337. wchar_t FileName[],
  338. error_status_t ErrorCode,
  339. int Location,
  340. error_status_t * pStatus
  341. )
  342. {
  343. VALIDATE_SEND_COOKIE (Cookie)
  344. struct SEND_FAILURE_DATA Data;
  345. COPYDATASTRUCT cStruct;
  346. CWnd* progressDlg = (CWnd*)Cookie;
  347. StringCbCopy(Data.FileName,sizeof(Data.FileName), FileName);
  348. Data.Location = (FAILURE_LOCATION)Location;
  349. Data.Error = ErrorCode;
  350. cStruct.cbData = sizeof(SEND_FAILURE_DATA);
  351. cStruct.lpData = &Data;
  352. progressDlg->SendMessage(WM_COPYDATA, (WPARAM) 0, (LPARAM)(&cStruct));
  353. *pStatus = 0;
  354. }
  355. void _SendComplete(
  356. handle_t RpcBinding,
  357. COOKIE Cookie,
  358. __int64 BytesTransferred,
  359. error_status_t* pStatus
  360. )
  361. {
  362. VALIDATE_SEND_COOKIE (Cookie)
  363. CWnd* progressDlg = (CWnd*)Cookie;
  364. progressDlg->PostMessage(WM_APP_SEND_COMPLETE);
  365. *pStatus = 0;
  366. }
  367. error_status_t
  368. _ReceiveInProgress(
  369. handle_t RpcBinding,
  370. wchar_t MachineName[],
  371. COOKIE * pCookie,
  372. boolean bSuppressRecvConf
  373. )
  374. {
  375. struct MSG_RECEIVE_IN_PROGRESS msg;
  376. msg.MachineName = MachineName;
  377. msg.pCookie = pCookie;
  378. msg.bSuppressRecvConf = bSuppressRecvConf;
  379. msg.status = ~0UL;
  380. appController->SendMessage( WM_APP_RECV_IN_PROGRESS, (WPARAM) &msg );
  381. return msg.status;
  382. }
  383. error_status_t
  384. _GetPermission(
  385. handle_t RpcBinding,
  386. COOKIE Cookie,
  387. wchar_t Name[],
  388. boolean fDirectory
  389. )
  390. {
  391. struct MSG_GET_PERMISSION msg;
  392. msg.Cookie = Cookie;
  393. msg.Name = Name;
  394. msg.fDirectory = fDirectory;
  395. msg.status = ~0UL;
  396. appController->SendMessage( WM_APP_GET_PERMISSION, (WPARAM) &msg );
  397. return msg.status;
  398. }
  399. error_status_t
  400. _ReceiveFinished(
  401. handle_t RpcBinding,
  402. COOKIE Cookie,
  403. error_status_t Status
  404. )
  405. {
  406. struct MSG_RECEIVE_FINISHED msg;
  407. msg.Cookie = Cookie;
  408. msg.ReceiveStatus = Status;
  409. msg.status = ~0UL;
  410. appController->SendMessage( WM_APP_RECV_FINISHED, (WPARAM) &msg );
  411. return msg.status;
  412. }
  413. void _DeviceInRange(
  414. handle_t RpcBinding,
  415. POBEX_DEVICE_LIST device,
  416. error_status_t* pStatus
  417. )
  418. {
  419. appController->PostMessage (WM_APP_KILL_TIMER);
  420. LONG NewLinkCount = InterlockedIncrement(&g_lLinkOnDesktop);
  421. BOOL Result;
  422. if (NewLinkCount == 1) {
  423. //
  424. // the link count went from zero to 1, create the links now
  425. //
  426. Result=CreateLinks();
  427. if (!Result) {
  428. //
  429. // could not create the links
  430. //
  431. InterlockedExchange(&g_lLinkOnDesktop,0);
  432. }
  433. }
  434. g_deviceList= device;
  435. *pStatus = 0;
  436. }
  437. void _NoDeviceInRange(
  438. handle_t RpcBinding,
  439. error_status_t* pStatus
  440. )
  441. {
  442. InterlockedExchange(&g_lLinkOnDesktop,0);
  443. RemoveLinks();
  444. g_deviceList = NULL;
  445. if (0 == g_lUIComponentCount) {
  446. //
  447. // nothing displayed, start timer to shutdown app if no device comeback some.
  448. //
  449. appController->PostMessage (WM_APP_START_TIMER);
  450. }
  451. *pStatus = 0;
  452. }
  453. VOID
  454. CloseDownUI(
  455. VOID
  456. )
  457. {
  458. if (0 == g_lUIComponentCount) {
  459. if (appController != NULL) {
  460. appController->PostMessage (WM_CLOSE);
  461. }
  462. } else {
  463. if (appController != NULL) {
  464. appController->SessionOver();
  465. }
  466. }
  467. return;
  468. }
  469. void _Message(
  470. handle_t RpcBinding,
  471. wchar_t String[]
  472. )
  473. {
  474. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  475. CString szTitle;
  476. szTitle.LoadString (IDS_CAPTION);
  477. InterlockedIncrement (&g_lUIComponentCount);
  478. ::MessageBox (NULL, String, (LPCTSTR) szTitle, MB_OK);
  479. BOOL fNoUIComponents = (0 == InterlockedDecrement (&g_lUIComponentCount));
  480. if (appController && fNoUIComponents && ! g_deviceList.GetDeviceCount())
  481. {
  482. //there are no UI components displayed and there are no devices in
  483. //range. Start the timer. If the timer expires, the app. will quit.
  484. appController->PostMessage (WM_APP_START_TIMER);
  485. }
  486. }
  487. error_status_t
  488. _ShutdownUi(handle_t RpcBinding)
  489. {
  490. appController->PostMessage( WM_CLOSE );
  491. return 0;
  492. }
  493. error_status_t
  494. _ShutdownRequested(
  495. handle_t RpcBinding,
  496. boolean * pAnswer
  497. )
  498. {
  499. WCHAR pwszCaption [50];
  500. WCHAR pwszMessage [MAX_PATH];
  501. *pAnswer = TRUE;
  502. if (appController)
  503. {
  504. appController->PostMessage (WM_APP_KILL_TIMER);
  505. }
  506. if (! ::LoadString ( g_hInstance, IDS_CAPTION, pwszCaption, 50))
  507. {
  508. return ERROR_NOT_ENOUGH_MEMORY;
  509. }
  510. if (! ::LoadString ( g_hInstance, IDS_SHUTDOWN_MESSAGE, pwszMessage, MAX_PATH))
  511. {
  512. return ERROR_NOT_ENOUGH_MEMORY;
  513. }
  514. //display a message box with YES / NO buttons
  515. if (IDYES == ::MessageBox (appController->m_hWnd, pwszMessage, pwszCaption,
  516. MB_ICONEXCLAMATION | MB_YESNO | MB_SYSTEMMODAL | MB_SETFOREGROUND))
  517. {
  518. *pAnswer = TRUE;
  519. }
  520. else
  521. {
  522. *pAnswer = FALSE;
  523. }
  524. return 0;
  525. }
  526. //////////////////////////////////////////////////////////////////////////////
  527. //Create links on the desktop and in the Send To menu to this executable file
  528. BOOL
  529. CreateLinks(
  530. VOID
  531. )
  532. {
  533. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  534. HRESULT Result=E_FAIL;
  535. LONG i;
  536. TCHAR lpszFullExeName [2*MAX_PATH];
  537. TCHAR lpszShortcutName[2*MAX_PATH];
  538. CString szDesc;
  539. szDesc.LoadString (IDS_SHTCUT_DESC);
  540. //
  541. // create the desktop link
  542. //
  543. if (GetShortcutInfo(lpszShortcutName,sizeof(lpszShortcutName)/sizeof(TCHAR), lpszFullExeName,sizeof(lpszFullExeName)/sizeof(TCHAR))) {
  544. #if 0
  545. OutputDebugString(lpszShortcutName);
  546. OutputDebugStringA("\n");
  547. #endif
  548. Result=CreateShortcut (lpszFullExeName, lpszShortcutName, (LPCTSTR) szDesc);
  549. if (SUCCEEDED(Result)) {
  550. } else {
  551. #if DB
  552. OutputDebugStringA("Could not create desktop link\n");
  553. #endif
  554. }
  555. } else {
  556. #if DBG
  557. OutputDebugStringA("Could not get desktop path\n");
  558. #endif
  559. }
  560. if (!SUCCEEDED(Result)) {
  561. return FALSE;
  562. }
  563. //
  564. // create the send to link
  565. //
  566. if (GetSendToInfo(lpszShortcutName,sizeof(lpszShortcutName)/sizeof(TCHAR) ,lpszFullExeName,sizeof(lpszFullExeName)/sizeof(TCHAR))) {
  567. Result=CreateShortcut (lpszFullExeName, lpszShortcutName, (LPCTSTR) szDesc);
  568. if (SUCCEEDED(Result)) {
  569. } else {
  570. #if DBG
  571. OutputDebugStringA("Could not create desktop link\n");
  572. #endif
  573. }
  574. } else {
  575. #if DBG
  576. OutputDebugStringA("Could get sendto path\n");
  577. #endif
  578. }
  579. return SUCCEEDED(Result);
  580. }
  581. //////////////////////////////////////////////////////////////////////////////
  582. // CreateShortcut - uses the shell's IShellLink and IPersistFile interfaces
  583. // to create and store a shortcut to the specified object.
  584. HRESULT CreateShortcut (LPCTSTR lpszExe, LPCTSTR lpszLink, LPCTSTR lpszDesc)
  585. {
  586. HRESULT hres;
  587. IShellLink* psl;
  588. hres = CoInitialize(NULL);
  589. if (FAILED(hres))
  590. return hres;
  591. // Get a pointer to the IShellLink interface.
  592. hres = CoCreateInstance(CLSID_ShellLink, NULL,
  593. CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
  594. if (SUCCEEDED(hres)) {
  595. IPersistFile* ppf;
  596. // Set the path to the shortcut target and add the
  597. // description.
  598. psl->SetPath(lpszExe);
  599. psl->SetDescription(lpszDesc);
  600. // Query IShellLink for the IPersistFile interface for saving the
  601. // shortcut in persistent storage.
  602. hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
  603. if (SUCCEEDED(hres)) {
  604. // Save the link by calling IPersistFile::Save.
  605. hres = ppf->Save(lpszLink, TRUE);
  606. ppf->Release();
  607. }
  608. psl->Release();
  609. }
  610. return SUCCEEDED(hres)?S_OK:E_FAIL;
  611. }
  612. void RemoveLinks (void)
  613. {
  614. TCHAR lpszShortcutName[2 * MAX_PATH];
  615. TCHAR lpszFullExeName[2 * MAX_PATH];
  616. //delete the desktop shortcut
  617. if (GetShortcutInfo (lpszShortcutName,sizeof(lpszShortcutName)/sizeof(TCHAR), lpszFullExeName,sizeof(lpszFullExeName)/sizeof(TCHAR))) {
  618. DeleteFile (lpszShortcutName);
  619. }
  620. //delete the send to shortcut
  621. //
  622. if (GetSendToInfo (lpszShortcutName,sizeof(lpszShortcutName)/sizeof(TCHAR), lpszFullExeName,sizeof(lpszFullExeName)/sizeof(TCHAR))) {
  623. DeleteFile (lpszShortcutName);
  624. }
  625. }
  626. BOOL GetShortcutInfo (
  627. LPTSTR lpszShortcutName,
  628. ULONG ShortCutNameLength,
  629. LPTSTR lpszFullExeName,
  630. ULONG ExeNameLength
  631. )
  632. {
  633. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  634. *lpszShortcutName = '\0'; //precautionary measures
  635. *lpszFullExeName = '\0';
  636. CString szExe;
  637. CString szShtCut;
  638. int len;
  639. szExe.LoadString (IDS_EXE);
  640. szShtCut.LoadString (IDS_DESKTOP_SHTCUT);
  641. len = GetSystemDirectory (lpszFullExeName, ExeNameLength);
  642. if (0 == len) {
  643. return FALSE;
  644. }
  645. StringCchCat(lpszFullExeName,ExeNameLength,LPCTSTR (szExe));
  646. if('\0' == g_lpszDesktopFolder[0]) //try once again if we had failed before, or maybe this is the first time
  647. {
  648. if (!SHGetSpecialFolderPath(NULL, g_lpszDesktopFolder,
  649. CSIDL_DESKTOPDIRECTORY, 0))
  650. {
  651. g_lpszDesktopFolder[0] = '\0'; //we failed so give up.
  652. return FALSE;
  653. }
  654. }
  655. StringCchCopy(lpszShortcutName,ShortCutNameLength, g_lpszDesktopFolder);
  656. StringCchCat(lpszShortcutName,ShortCutNameLength, (LPCTSTR) szShtCut);
  657. return TRUE;
  658. }
  659. BOOL GetSendToInfo (
  660. LPTSTR lpszSendToName,
  661. ULONG SendToNameLength,
  662. LPTSTR lpszFullExeName,
  663. ULONG FullExeNameLength
  664. )
  665. {
  666. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  667. *lpszSendToName = TEXT('\0'); //precautionary measures
  668. *lpszFullExeName = TEXT('\0');
  669. CString szExe;
  670. CString szSendTo;
  671. int len;
  672. szExe.LoadString (IDS_EXE);
  673. szSendTo.LoadString (IDS_SENDTO_SHTCUT);
  674. len = GetSystemDirectory (lpszFullExeName, FullExeNameLength);
  675. if (0 == len) {
  676. return FALSE;
  677. }
  678. StringCchCat(lpszFullExeName,FullExeNameLength, (LPCTSTR) szExe);
  679. if ('\0' == g_lpszSendToFolder[0]) //try once again if we had failed before, or maybe this is the first time
  680. {
  681. if (!SHGetSpecialFolderPath(NULL, g_lpszSendToFolder,
  682. CSIDL_SENDTO, 0))
  683. {
  684. g_lpszSendToFolder[0] = TEXT('\0');
  685. return FALSE;
  686. }
  687. }
  688. StringCchCopy(lpszSendToName,SendToNameLength, g_lpszSendToFolder);
  689. StringCchCat(lpszSendToName, SendToNameLength,(LPCTSTR) szSendTo);
  690. return TRUE;
  691. }
  692. //+--------------------------------------------------------------------------
  693. //
  694. // Member: CError::ConstructMessage
  695. //
  696. // Synopsis: this is an internal helper function that constructs a message
  697. // from the available error codes it is called by both ShowMessage
  698. //
  699. // Arguments: [in] argList : the va_list of arguments
  700. // [out] szErrMsg : the formatted error message
  701. //
  702. // Returns: nothing
  703. //
  704. // History: 10/2/1998 RahulTh created
  705. //
  706. // Notes:
  707. //
  708. //---------------------------------------------------------------------------
  709. void CError::ConstructMessage (va_list argList, CString& szErrMsg)
  710. {
  711. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  712. TCHAR lpszMessage[2048];
  713. szErrMsg.LoadString (m_msgID);
  714. StringCbVPrintf(lpszMessage, sizeof(lpszMessage),(LPCTSTR) szErrMsg, argList);
  715. szErrMsg = lpszMessage;
  716. if (ERROR_SUCCESS != m_winErr)
  717. {
  718. LPVOID lpMsgBuf;
  719. DWORD dwRet;
  720. dwRet = ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
  721. FORMAT_MESSAGE_FROM_SYSTEM |
  722. FORMAT_MESSAGE_IGNORE_INSERTS,
  723. NULL,
  724. m_winErr,
  725. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  726. (LPTSTR) &lpMsgBuf,
  727. 0,
  728. NULL
  729. );
  730. if (dwRet)
  731. {
  732. szErrMsg += TEXT("\n\n");
  733. szErrMsg += (LPCTSTR) lpMsgBuf;
  734. LocalFree (lpMsgBuf);
  735. }
  736. }
  737. }
  738. //+--------------------------------------------------------------------------
  739. //
  740. // Member: CError::ShowMessage
  741. //
  742. // Synopsis: displays an error message in a message box based on the
  743. // members of the object
  744. //
  745. // Arguments: message id for the error + more
  746. //
  747. // Returns: the return value of the message box
  748. //
  749. // History: 10/1/1998 RahulTh created
  750. //
  751. // Notes: if the resultant message is longer than 2048 characters
  752. // then result is unpredictable and may also cause AVs.
  753. // but this is a limitation of wvsprintf. However, this is not
  754. // so bad since we can make sure that we do not have any error
  755. // message that exceed this self imposed limit
  756. //
  757. //---------------------------------------------------------------------------
  758. int CError::ShowMessage (UINT errID, ...)
  759. {
  760. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  761. va_list argList;
  762. CString szErrMsg;
  763. CString szTitle;
  764. m_msgID = errID; //update the message ID with the new one
  765. szTitle.LoadString (m_titleID);
  766. va_start (argList, errID);
  767. ConstructMessage (argList, szErrMsg);
  768. va_end (argList);
  769. return ::MessageBox (m_hWndParent, (LPCTSTR)szErrMsg,
  770. (LPCTSTR) szTitle, m_nStyle);
  771. }