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.

786 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999.
  5. //
  6. // File: srchutil.cxx
  7. //
  8. // Contents:
  9. //
  10. // History: 15 Aug 1996 DLee Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "pch.cxx"
  14. #pragma hdrstop
  15. void SetReg(
  16. WCHAR const * pwcName,
  17. WCHAR const * pwcValue)
  18. {
  19. HKEY hKeyParent;
  20. if (ERROR_SUCCESS ==
  21. RegOpenKeyEx(HKEY_CURRENT_USER,CISEARCH_PARENT_REG_KEY,0,
  22. KEY_ALL_ACCESS,&hKeyParent))
  23. {
  24. DWORD dwDisp;
  25. HKEY hKey;
  26. if (ERROR_SUCCESS ==
  27. RegCreateKeyEx(hKeyParent,CISEARCH_REG_SUBKEY,0,L"",
  28. REG_OPTION_NON_VOLATILE,
  29. KEY_ALL_ACCESS,0,&hKey,&dwDisp))
  30. {
  31. RegSetValueEx(hKey,pwcName,0,REG_SZ,(LPBYTE) pwcValue,
  32. sizeof(WCHAR) * (wcslen(pwcValue) + 1));
  33. RegCloseKey(hKey);
  34. }
  35. RegCloseKey(hKeyParent);
  36. }
  37. } //SetReg
  38. BOOL GetReg(
  39. WCHAR const * pwcName,
  40. WCHAR * pwcValue,
  41. DWORD * pdwSize)
  42. {
  43. BOOL fOk = FALSE;
  44. HKEY hKeyParent;
  45. if (ERROR_SUCCESS ==
  46. RegOpenKeyEx(HKEY_CURRENT_USER,CISEARCH_PARENT_REG_KEY,0,
  47. KEY_ALL_ACCESS,&hKeyParent))
  48. {
  49. DWORD dwDisp;
  50. HKEY hKey;
  51. if (ERROR_SUCCESS ==
  52. RegCreateKeyEx(hKeyParent,CISEARCH_REG_SUBKEY,0,L"",
  53. REG_OPTION_NON_VOLATILE,
  54. KEY_ALL_ACCESS,0,&hKey,&dwDisp))
  55. {
  56. DWORD dwType;
  57. if (ERROR_SUCCESS == RegQueryValueEx(hKey,pwcName,0,&dwType,
  58. (LPBYTE) pwcValue,pdwSize))
  59. fOk = TRUE;
  60. RegCloseKey(hKey);
  61. }
  62. RegCloseKey(hKeyParent);
  63. }
  64. return fOk;
  65. } //GetReg
  66. LCID GetRegLCID(
  67. WCHAR const * pwcName,
  68. LCID defLCID )
  69. {
  70. WCHAR awc[100];
  71. DWORD dw = sizeof awc / sizeof awc[0];
  72. if (GetReg(pwcName,awc,&dw))
  73. return _wtoi(awc);
  74. else
  75. return defLCID;
  76. } //GetRegLCID
  77. void SetRegLCID(
  78. WCHAR const * pwcName,
  79. LCID lcid )
  80. {
  81. WCHAR awc[20];
  82. // itow is not in all C runtimes _itow(iValue,awc,10);
  83. swprintf( awc, L"%d", lcid );
  84. SetReg( pwcName, awc );
  85. } //SetRegLCID
  86. int GetRegInt(
  87. WCHAR const * pwcName,
  88. int iDef)
  89. {
  90. WCHAR awc[100];
  91. DWORD dw = sizeof awc / sizeof awc[0];
  92. if (GetReg(pwcName,awc,&dw))
  93. return _wtoi(awc);
  94. else
  95. return iDef;
  96. } //GetRegInt
  97. void SetRegInt(
  98. WCHAR const * pwcName,
  99. int iValue)
  100. {
  101. WCHAR awc[20];
  102. // itow is not in all C runtimes _itow(iValue,awc,10);
  103. swprintf( awc, L"%d", iValue );
  104. SetReg( pwcName, awc );
  105. } //SetRegInt
  106. BOOL IsSpecificClass(
  107. HWND hwnd,
  108. WCHAR const * pwcClass)
  109. {
  110. WCHAR awcClass[60];
  111. GetClassName(hwnd,awcClass,(sizeof awcClass / sizeof WCHAR) - 1);
  112. return !wcscmp( awcClass, pwcClass );
  113. } //IsSpecificClass
  114. int GetLineHeight(
  115. HWND hwnd,
  116. HFONT hFont)
  117. {
  118. if (hFont == 0)
  119. hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
  120. HDC hdc;
  121. int iHeight=0;
  122. if (hdc = GetDC(hwnd))
  123. {
  124. HFONT hOldFont;
  125. if (hOldFont = (HFONT) SelectObject(hdc,hFont))
  126. {
  127. TEXTMETRIC tm;
  128. GetTextMetrics(hdc,&tm);
  129. iHeight = (tm.tmHeight + 2 * tm.tmExternalLeading);
  130. SelectObject(hdc,hOldFont);
  131. }
  132. ReleaseDC(hwnd,hdc);
  133. }
  134. return iHeight;
  135. } //GetLineHeight
  136. int GetAvgWidth(
  137. HWND hwnd,
  138. HFONT hFont)
  139. {
  140. if (hFont == 0)
  141. hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
  142. HDC hdc;
  143. LONG cpWidth = 0;
  144. if (hdc = GetDC(hwnd))
  145. {
  146. HFONT hOldFont;
  147. if (hOldFont = (HFONT) SelectObject(hdc,hFont))
  148. {
  149. TEXTMETRIC tm;
  150. GetTextMetrics(hdc,&tm);
  151. cpWidth = tm.tmAveCharWidth;
  152. SelectObject(hdc,hOldFont);
  153. }
  154. ReleaseDC(hwnd,hdc);
  155. }
  156. return cpWidth;
  157. } //GetAvgWidth
  158. INT_PTR DoModalDialog(
  159. DLGPROC fp,
  160. HWND hParent,
  161. WCHAR * pwcName,
  162. LPARAM lParam)
  163. {
  164. return DialogBoxParam(MyGetWindowInstance(hParent),
  165. pwcName,
  166. hParent,
  167. fp,
  168. lParam);
  169. } //DoModalDialog
  170. void SaveWindowRect(
  171. HWND hwnd,
  172. WCHAR const * pwc )
  173. {
  174. if (! (IsZoomed(hwnd) || IsIconic(hwnd)))
  175. {
  176. RECT rc;
  177. GetWindowRect(hwnd,&rc);
  178. WCHAR awc[100];
  179. swprintf(awc,L"%d %d %d %d",rc.left,rc.top,rc.right,rc.bottom);
  180. SetReg( pwc, awc );
  181. }
  182. } //SaveWindowRect
  183. BOOL LoadWindowRect(
  184. int * left,
  185. int * top,
  186. int * right,
  187. int * bottom,
  188. WCHAR const * pwc )
  189. {
  190. WCHAR awc[100];
  191. DWORD dw = sizeof awc / sizeof awc[0];
  192. if ( GetReg( pwc, awc, &dw ) )
  193. {
  194. swscanf(awc,L"%d %d %d %d",left,top,right,bottom);
  195. *right = *right - *left;
  196. *bottom = *bottom - *top;
  197. return TRUE;
  198. }
  199. else
  200. {
  201. *left = *top = *right = *bottom = CW_USEDEFAULT;
  202. return FALSE;
  203. }
  204. } //LoadWindowRect
  205. int GetWindowState(
  206. BOOL bApp)
  207. {
  208. WCHAR awcValue[100],awcBuf[100];
  209. if (bApp)
  210. wcscpy(awcBuf,L"main");
  211. else
  212. wcscpy(awcBuf,L"mdi");
  213. wcscat(awcBuf,L"-state");
  214. DWORD dw = sizeof awcValue / sizeof awcValue[0];
  215. int iState;
  216. if (GetReg(awcBuf,awcValue,&dw))
  217. iState = awcValue[0] - L'0';
  218. else
  219. iState = 1;
  220. return iState;
  221. } //GetWindowState
  222. void PassOnToEdit(
  223. UINT msg,
  224. WPARAM wParam,
  225. LPARAM lParam)
  226. {
  227. HWND hwndActive = GetFocus();
  228. if ( 0 != hwndActive )
  229. {
  230. WCHAR awcBuf[60];
  231. int r = GetClassName(hwndActive,awcBuf,(sizeof awcBuf / sizeof WCHAR) - 1);
  232. if ( 0 == r )
  233. return;
  234. if ( ( !_wcsicmp( awcBuf, L"Edit" ) ) ||
  235. ( !_wcsicmp( awcBuf, L"RichEdit" ) ) )
  236. SendMessage( hwndActive, msg, wParam, lParam);
  237. }
  238. } //PassOnToEdit
  239. void WINAPI CenterDialog(
  240. HWND hdlg)
  241. {
  242. RECT rcParent;
  243. RECT rc;
  244. GetWindowRect(hdlg,(LPRECT) &rc);
  245. GetWindowRect(GetParent(hdlg),(LPRECT) &rcParent);
  246. LONG xbias = rcParent.left + (rcParent.right - rcParent.left)/2;
  247. LONG ybias = rcParent.top + (rcParent.bottom - rcParent.top)/2;
  248. LONG lWidth = rc.right - rc.left;
  249. LONG lHeight = rc.bottom - rc.top;
  250. MoveWindow(hdlg, xbias - lWidth/2,
  251. ybias - lHeight/2,
  252. lWidth,lHeight,FALSE);
  253. } //CenterDialog
  254. //+---------------------------------------------------------------------------
  255. //
  256. // Function: ConvertGroupingStringToInt
  257. //
  258. // Synopsis: Converts a grouping string from the registry to an integer,
  259. // as required by the Win32 number formatting API
  260. //
  261. // History: 5-Feb-99 dlee Stole from the Win32 implementation
  262. //
  263. //----------------------------------------------------------------------------
  264. int ConvertGroupingStringToInt( WCHAR const * pwcGrouping )
  265. {
  266. XGrowable<WCHAR> xDest( 1 + wcslen( pwcGrouping ) );
  267. WCHAR * pDest = xDest.Get();
  268. //
  269. // Filter out all non-numeric values and all zero values.
  270. // Store the result in the destination buffer.
  271. //
  272. WCHAR const * pSrc = pwcGrouping;
  273. while (0 != *pSrc)
  274. {
  275. if ( ( *pSrc < L'1' ) || ( *pSrc > L'9' ) )
  276. {
  277. pSrc++;
  278. }
  279. else
  280. {
  281. if (pSrc != pDest)
  282. *pDest = *pSrc;
  283. pSrc++;
  284. pDest++;
  285. }
  286. }
  287. //
  288. // Make sure there is something in the destination buffer.
  289. // Also, see if we need to add a zero in the case of 3;2 becomes 320.
  290. //
  291. if ( ( pDest == xDest.Get() ) || ( *(pSrc - 1) != L'0' ) )
  292. {
  293. *pDest = L'0';
  294. pDest++;
  295. }
  296. // Null terminate the buffer.
  297. *pDest = 0;
  298. // Convert the string to an integer.
  299. return _wtoi( xDest.Get() );
  300. } //ConvertGroupingStringToInt
  301. void LoadNumberFormatInfo(
  302. NUMBERFMT & rFormat)
  303. {
  304. LCID lcid = GetUserDefaultLCID();
  305. WCHAR awcBuf[cwcBufSize];
  306. // Get the number of decimal digits.
  307. GetLocaleInfo(lcid,LOCALE_IDIGITS,awcBuf,cwcBufSize);
  308. rFormat.NumDigits = _wtoi(awcBuf);
  309. // Get the leading zero in decimal fields option.
  310. GetLocaleInfo(lcid,LOCALE_ILZERO,awcBuf,cwcBufSize);
  311. rFormat.LeadingZero = _wtoi(awcBuf);
  312. // Get the negative ordering.
  313. GetLocaleInfo(lcid,LOCALE_INEGNUMBER,awcBuf,cwcBufSize);
  314. rFormat.NegativeOrder = _wtoi(awcBuf);
  315. // Get the grouping left of the decimal.
  316. GetLocaleInfo(lcid,LOCALE_SGROUPING,awcBuf,cwcBufSize);
  317. rFormat.Grouping = ConvertGroupingStringToInt( awcBuf );
  318. // Get the decimal separator.
  319. GetLocaleInfo(lcid,LOCALE_SDECIMAL,awcBuf,cwcBufSize);
  320. rFormat.lpDecimalSep = new WCHAR[wcslen(awcBuf) + 1];
  321. wcscpy(rFormat.lpDecimalSep,awcBuf);
  322. // Get the thousand separator.
  323. GetLocaleInfo(lcid,LOCALE_STHOUSAND,awcBuf,cwcBufSize);
  324. rFormat.lpThousandSep = new WCHAR[wcslen(awcBuf) + 1];
  325. wcscpy(rFormat.lpThousandSep,awcBuf);
  326. } //LoadNumberFormatInfo
  327. void FreeNumberFormatInfo(
  328. NUMBERFMT & rFormat)
  329. {
  330. delete rFormat.lpDecimalSep;
  331. delete rFormat.lpThousandSep;
  332. } //FreeNumberFormatInfo
  333. void SearchError(
  334. HWND hParent,
  335. ULONG dwErrorID,
  336. WCHAR const * pwcTitle)
  337. {
  338. CResString str( dwErrorID );
  339. MessageBox( hParent, str.Get(), pwcTitle, MB_OK | MB_ICONEXCLAMATION );
  340. } //SearchError
  341. void PutInClipboard(
  342. WCHAR const * pwcBuffer )
  343. {
  344. if ( OpenClipboard( App.AppWindow() ) )
  345. {
  346. EmptyClipboard();
  347. HGLOBAL hglbCopy = GlobalAlloc( GMEM_DDESHARE,
  348. ( wcslen( pwcBuffer ) + 1 ) *
  349. sizeof WCHAR );
  350. if ( 0 != hglbCopy )
  351. {
  352. WCHAR *pwc = (WCHAR *) GlobalLock( hglbCopy );
  353. wcscpy( pwc, pwcBuffer );
  354. GlobalUnlock( hglbCopy );
  355. SetClipboardData( CF_UNICODETEXT, hglbCopy );
  356. }
  357. CloseClipboard();
  358. }
  359. } //PutInClipboard
  360. BOOL GetRegEditor(
  361. WCHAR const * pwcName,
  362. WCHAR * pwcValue,
  363. DWORD * pdwSize)
  364. {
  365. BOOL fOk = FALSE;
  366. HKEY hKeyParent;
  367. if (ERROR_SUCCESS ==
  368. RegOpenKeyEx(HKEY_CURRENT_USER,L"software\\microsoft",0,
  369. KEY_ALL_ACCESS,&hKeyParent))
  370. {
  371. DWORD dwDisp;
  372. HKEY hKey;
  373. if (ERROR_SUCCESS ==
  374. RegCreateKeyEx(hKeyParent,L"Windiff",0,L"",
  375. REG_OPTION_NON_VOLATILE,
  376. KEY_ALL_ACCESS,0,&hKey,&dwDisp))
  377. {
  378. DWORD dwType;
  379. if (ERROR_SUCCESS == RegQueryValueEx(hKey,pwcName,0,&dwType,
  380. (LPBYTE) pwcValue,pdwSize))
  381. fOk = TRUE;
  382. RegCloseKey(hKey);
  383. }
  384. RegCloseKey(hKeyParent);
  385. }
  386. return fOk;
  387. } //GetRegEditor
  388. void FormatSrchError( SCODE sc, WCHAR * pwc, LCID lcid )
  389. {
  390. LCID SaveLCID = GetThreadLocale();
  391. SetThreadLocale( lcid );
  392. ULONG Win32status = sc;
  393. if ( (Win32status & (FACILITY_WIN32 << 16)) == (FACILITY_WIN32 << 16) )
  394. Win32status &= ~( 0x80000000 | (FACILITY_WIN32 << 16) );
  395. if ( ! FormatMessage( FORMAT_MESSAGE_FROM_HMODULE,
  396. GetModuleHandle(L"query.dll"),
  397. sc,
  398. 0,
  399. pwc,
  400. MAX_PATH,
  401. 0 ) )
  402. {
  403. //
  404. // Try looking up the error in the Win32 list of error codes
  405. //
  406. if ( ! FormatMessage( FORMAT_MESSAGE_FROM_HMODULE,
  407. GetModuleHandle(L"kernel32.dll"),
  408. Win32status,
  409. 0,
  410. pwc,
  411. MAX_PATH,
  412. 0 ) )
  413. {
  414. swprintf( pwc, L"0x%x", sc );
  415. }
  416. }
  417. SetThreadLocale(SaveLCID);
  418. } //FormatSrchError
  419. BOOL CopyURL( WCHAR const * pwcURL, WCHAR * awcTempName )
  420. {
  421. WCHAR const * pwcSlash = wcsrchr( pwcURL, L'/' );
  422. if ( 0 == pwcSlash )
  423. return FALSE;
  424. pwcSlash++;
  425. DWORD cwc = GetTempPath( MAX_PATH, awcTempName );
  426. if ( 0 == cwc || cwc > MAX_PATH )
  427. return FALSE;
  428. wcscat( awcTempName, pwcSlash );
  429. XIHandle xhI( InternetOpenW( L"srch",
  430. INTERNET_OPEN_TYPE_PRECONFIG,
  431. 0,
  432. 0,
  433. 0 ) );
  434. if ( xhI.IsNull() )
  435. return FALSE;
  436. XIHandle xhUrl( InternetOpenUrlW( xhI.Get(), pwcURL, 0, 0,
  437. INTERNET_FLAG_RELOAD |
  438. INTERNET_FLAG_DONT_CACHE |
  439. INTERNET_FLAG_PRAGMA_NOCACHE |
  440. INTERNET_FLAG_NO_CACHE_WRITE |
  441. INTERNET_FLAG_NO_COOKIES |
  442. INTERNET_FLAG_NO_UI,
  443. 0 ) );
  444. if ( xhUrl.IsNull() )
  445. return FALSE;
  446. FILE * fp = _wfopen( awcTempName, L"wb" );
  447. if ( 0 == fp )
  448. return FALSE;
  449. char ac[ 1024 * 16 ];
  450. do
  451. {
  452. DWORD cbRead = 0;
  453. BOOL fOK = InternetReadFile( xhUrl.Get(),
  454. ac,
  455. sizeof ac,
  456. &cbRead );
  457. if ( !fOK )
  458. {
  459. fclose( fp );
  460. return FALSE;
  461. }
  462. if ( 0 == cbRead )
  463. break;
  464. fwrite( ac, 1, cbRead, fp );
  465. } while( TRUE );
  466. fclose( fp );
  467. return TRUE;
  468. } //CopyURL
  469. BOOL InvokeBrowser(
  470. WCHAR const * pwcFilePath,
  471. DBCOMMANDTREE * prstQuery )
  472. {
  473. WCHAR awcTempFile[MAX_PATH];
  474. BOOL fDeleteWhenDone = FALSE;
  475. if ( !_wcsnicmp( pwcFilePath, L"file:", 5 ) )
  476. pwcFilePath += 5;
  477. else if ( !_wcsnicmp( pwcFilePath, L"http:", 5 ) )
  478. {
  479. if ( !CopyURL( pwcFilePath, awcTempFile ) )
  480. return FALSE;
  481. pwcFilePath = awcTempFile;
  482. fDeleteWhenDone = TRUE;
  483. }
  484. BOOL fOK = TRUE;
  485. CQueryResult *pResult = new CQueryResult( pwcFilePath, prstQuery, fDeleteWhenDone );
  486. // call internal mdi browser
  487. if (pwcFilePath)
  488. {
  489. HWND h = App.CreateBrowser( pwcFilePath, (LPARAM) pResult );
  490. if ( 0 == h )
  491. {
  492. WCHAR awcError[ MAX_PATH ];
  493. FormatSrchError( App.BrowseLastError(), awcError, App.GetLocale() );
  494. WCHAR awcMsg[ MAX_PATH ];
  495. CResString strErr( IDS_ERR_CANT_BROWSE_FILE );
  496. swprintf( awcMsg, strErr.Get(), awcError );
  497. MessageBox( App.AppWindow(),
  498. awcMsg,
  499. pwcFilePath,
  500. MB_OK|MB_ICONEXCLAMATION );
  501. fOK = FALSE;
  502. }
  503. }
  504. return fOK;
  505. } //InvokeBrowser
  506. void ExecApp(
  507. WCHAR const * pwcCmd)
  508. {
  509. STARTUPINFO si;
  510. memset( &si, 0, sizeof si );
  511. si.cb = sizeof si;
  512. si.dwFlags = STARTF_USESHOWWINDOW;
  513. si.wShowWindow = SW_SHOWDEFAULT;
  514. PROCESS_INFORMATION pi;
  515. CreateProcess( 0, (WCHAR *) pwcCmd, 0, 0, FALSE, 0, 0, 0, &si, &pi );
  516. } //ExecApp
  517. BOOL ViewFile(
  518. WCHAR const * pwcPath,
  519. enumViewFile eViewType,
  520. int iLineNumber,
  521. DBCOMMANDTREE * prstQuery )
  522. {
  523. BOOL fOK = TRUE;
  524. WCHAR awcCmd[MAX_PATH + cwcBufSize];
  525. DWORD cbCmd = sizeof awcCmd / sizeof awcCmd[0];
  526. if ( fileOpen == eViewType )
  527. {
  528. HINSTANCE hinst = ShellExecute( HWND_DESKTOP,
  529. 0,
  530. pwcPath,
  531. 0,
  532. 0,
  533. SW_SHOWNORMAL );
  534. if ( 32 > (DWORD_PTR) hinst )
  535. {
  536. // if no app is registered for this extension, use notepad
  537. wcscpy( awcCmd, L"notepad " );
  538. wcscat( awcCmd, pwcPath );
  539. ExecApp( awcCmd );
  540. }
  541. }
  542. else if ( fileBrowse == eViewType )
  543. {
  544. fOK = InvokeBrowser( (WCHAR *) pwcPath, prstQuery );
  545. }
  546. else if ( fileEdit == eViewType )
  547. {
  548. WCHAR awcEditor[ MAX_PATH ];
  549. if ( GetReg( CISEARCH_REG_EDITOR, awcEditor, &cbCmd ) )
  550. {
  551. // cool -- use it.
  552. }
  553. else
  554. {
  555. // try to use windiff's configuration
  556. cbCmd = sizeof awcCmd;
  557. if ( GetRegEditor( L"Editor", awcEditor, &cbCmd ) )
  558. {
  559. WCHAR *p = wcsstr( awcEditor, L"%p" );
  560. if ( p )
  561. *(p+1) = L's';
  562. p = wcsstr( awcEditor, L"%l" );
  563. if ( p )
  564. *(p+1) = L'd';
  565. }
  566. else
  567. {
  568. //wcscpy( awcEditor, L"s %ws -#%d" );
  569. // no editor configured -- open the file
  570. return ViewFile( pwcPath, fileOpen, iLineNumber, prstQuery );
  571. }
  572. }
  573. TRY
  574. {
  575. swprintf( awcCmd, awcEditor, pwcPath, iLineNumber );
  576. ExecApp( awcCmd );
  577. }
  578. CATCH( CException, e )
  579. {
  580. fOK = FALSE;
  581. }
  582. END_CATCH;
  583. }
  584. return fOK;
  585. } //ViewFile
  586. BOOL GetCatListItem( const XGrowable<WCHAR> & const_xCatList,
  587. unsigned iItem,
  588. WCHAR * pwszMachine,
  589. WCHAR * pwszCatalog,
  590. WCHAR * pwszScope,
  591. BOOL & fDeep )
  592. {
  593. XGrowable<WCHAR> xCatList = const_xCatList;
  594. Win4Assert( pwszMachine && pwszCatalog && pwszScope );
  595. *pwszMachine = *pwszCatalog = *pwszScope = 0;
  596. fDeep = FALSE;
  597. unsigned ii;
  598. WCHAR * pStart = xCatList.Get();
  599. for( ii = 0; ii < iItem; ii++ )
  600. {
  601. pStart = wcschr( pStart, L';' );
  602. if ( pStart )
  603. {
  604. pStart++;
  605. }
  606. else
  607. break;
  608. if ( 0 == *pStart )
  609. {
  610. break;
  611. }
  612. }
  613. if ( 0 == pStart || 0 == *pStart )
  614. {
  615. return FALSE;
  616. }
  617. WCHAR * pEnd;
  618. // machine
  619. pEnd = wcschr( pStart, L',' );
  620. if ( !pEnd )
  621. {
  622. return FALSE;
  623. }
  624. *pEnd = 0;
  625. wcscpy( pwszMachine, pStart );
  626. pStart = pEnd + 1;
  627. // catalog
  628. pEnd = wcschr( pStart, L',' );
  629. if ( !pEnd )
  630. {
  631. return FALSE;
  632. }
  633. *pEnd = 0;
  634. wcscpy( pwszCatalog, pStart );
  635. pStart = pEnd + 1;
  636. // scope
  637. pEnd = wcschr( pStart, L',' );
  638. if ( !pEnd )
  639. {
  640. return FALSE;
  641. }
  642. *pEnd = 0;
  643. wcscpy( pwszScope, pStart );
  644. pStart = pEnd + 1;
  645. // depth
  646. fDeep = ( L'd' == *pStart || L'D' == *pStart );
  647. return TRUE;
  648. }