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.

408 lines
12 KiB

  1. #include <pch.cxx>
  2. #pragma hdrstop
  3. #include <ole2.h>
  4. #include "trkwks.hxx"
  5. #include "dltadmin.hxx"
  6. #include <shlobj.h>
  7. #include <shlguid.h>
  8. #define CB_LINK_CLIENT_MAX 512
  9. void
  10. DoCreateLink(IShellLink * pshlink, const TCHAR *ptszLink, const TCHAR *ptszSrc)
  11. {
  12. HRESULT hr;
  13. IPersistFile *pPersistFile = NULL;
  14. DWORD dwWritten;
  15. BYTE rgb[ CB_LINK_CLIENT_MAX ];
  16. ULONG cbPersist = 0;
  17. memset( rgb, 0, sizeof(rgb) );
  18. hr = pshlink->QueryInterface( IID_IPersistFile, (void**) &pPersistFile );
  19. if( FAILED(hr) )
  20. {
  21. _tprintf( TEXT("Couldn't QI IShellLink for IPersistFile (%08x)"), hr );
  22. goto Exit;
  23. }
  24. hr = pshlink->SetPath( ptszSrc );
  25. _tprintf( TEXT("IShellLink::SetPath returned %08X\n"), hr );
  26. if( S_OK != hr )
  27. goto Exit;
  28. hr = pPersistFile->Save( ptszLink, TRUE );
  29. if( FAILED(hr) )
  30. {
  31. _tprintf( TEXT("Couldn't persist IShellLink (%08x"), hr );
  32. goto Exit;
  33. }
  34. pPersistFile->SaveCompleted( ptszLink );
  35. Exit:
  36. RELEASE_INTERFACE( pPersistFile );
  37. return;
  38. }
  39. TCHAR *
  40. GetRestrict(DWORD r)
  41. {
  42. static TCHAR tszError[256];
  43. tszError[0] = 0;
  44. if (r == TRK_MEND_DEFAULT)
  45. {
  46. _tcscpy(tszError, TEXT("TRK_MEND_DEFAULT "));
  47. }
  48. if (r & TRK_MEND_DONT_USE_LOG)
  49. {
  50. _tcscat(tszError, TEXT("TRK_MEND_DONT_USE_LOG "));
  51. }
  52. if (r & TRK_MEND_DONT_USE_DC)
  53. {
  54. _tcscat(tszError, TEXT("TRK_MEND_DONT_USE_DC "));
  55. }
  56. if (r & TRK_MEND_SLEEP_DURING_MEND)
  57. {
  58. _tcscat(tszError, TEXT("TRK_MEND_SLEEP_DURING_SEARCH "));
  59. }
  60. if (r & TRK_MEND_DONT_SEARCH_ALL_VOLUMES)
  61. {
  62. _tcscat(tszError, TEXT("TRK_MEND_DONT_SEARCH_ALL_VOLUMES "));
  63. }
  64. if (r & TRK_MEND_DONT_USE_VOLIDS)
  65. {
  66. _tcscat(tszError, TEXT("TRK_MEND_DONT_USE_VOLIDS "));
  67. }
  68. return(tszError);
  69. }
  70. enum EXTRAFLAGS
  71. {
  72. EXTRAFLAG_SHOW_IDS = 1
  73. };
  74. extern "C"
  75. IID IID_ISLTracker
  76. = { /* 7c9e512f-41d7-11d1-8e2e-00c04fb9386d */
  77. 0x7c9e512f,
  78. 0x41d7,
  79. 0x11d1,
  80. {0x8e, 0x2e, 0x00, 0xc0, 0x4f, 0xb9, 0x38, 0x6d}
  81. };
  82. class ISLTracker : public IUnknown
  83. {
  84. public:
  85. STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj) PURE;
  86. STDMETHOD_(ULONG,AddRef) () PURE;
  87. STDMETHOD_(ULONG,Release) () PURE;
  88. STDMETHOD(Resolve)(HWND hwnd, DWORD fFlags, DWORD TrackerRestrictions) PURE;
  89. STDMETHOD(GetIDs)(CDomainRelativeObjId *pdroidBirth, CDomainRelativeObjId *pdroidLast, CMachineId *pmcid) PURE;
  90. }; // interface ISLTracker
  91. void
  92. DisplayIDs( ISLTracker *ptracker )
  93. {
  94. HRESULT hr = S_OK;
  95. CDomainRelativeObjId droidBirth, droidLast;
  96. CMachineId mcid;
  97. TCHAR tsz[ MAX_PATH ];
  98. TCHAR *ptsz = tsz;
  99. hr = ptracker->GetIDs( &droidBirth, &droidLast, &mcid );
  100. if( FAILED(hr) )
  101. {
  102. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't get IDs") ));
  103. TrkRaiseException( hr );
  104. }
  105. droidBirth.Stringize( tsz, sizeof(tsz) );
  106. _tprintf( TEXT("Birth =\t%s\n"), tsz );
  107. droidLast.Stringize( tsz, sizeof(tsz) );
  108. _tprintf( TEXT("Last =\t%s\n"), tsz );
  109. ptsz = tsz;
  110. mcid.Stringize(ptsz);
  111. _tprintf( TEXT("Machine =\t%s\n"), tsz );
  112. }
  113. void
  114. DoResolveLink(IShellLink * pshlink, const TCHAR * ptszLink, DWORD r, DWORD dwSLR, DWORD grfExtra,
  115. DWORD dwTimeout )
  116. {
  117. IPersistFile * pPersistFile = NULL;
  118. ISLTracker * ptracker = NULL;
  119. __try
  120. {
  121. DWORD dwRead;
  122. HRESULT hr;
  123. WCHAR wszPath[MAX_PATH+1];
  124. ULONG cbPath = sizeof(wszPath);
  125. WIN32_FIND_DATA fd;
  126. hr = pshlink->QueryInterface( IID_IPersistFile, (void**) &pPersistFile );
  127. if( FAILED(hr) )
  128. {
  129. TrkLog((TRKDBG_ERROR, TEXT("Couldn't QI for IPersistFile")));
  130. TrkRaiseException( hr );
  131. }
  132. hr = pPersistFile->Load( ptszLink, STGM_SHARE_EXCLUSIVE | STGM_READWRITE );
  133. if( FAILED(hr) )
  134. {
  135. TrkLog((TRKDBG_ERROR, TEXT("Couldn't load IShellLink")));
  136. TrkRaiseException( hr );
  137. }
  138. RELEASE_INTERFACE( pPersistFile );
  139. if( (SLR_NO_UI & dwSLR) )
  140. {
  141. if( 0 != dwTimeout )
  142. {
  143. dwTimeout = min( dwTimeout, 0xfffe );
  144. _tprintf( TEXT("Timeout = %d seconds\n"), dwTimeout/1000 );
  145. }
  146. }
  147. else if( 0 != dwTimeout )
  148. {
  149. _tprintf( TEXT("Timeout will be ignored (since SLR_NO_UI isn't set)\n") );
  150. }
  151. // Track it
  152. if( TRK_MEND_DEFAULT == r && 0 == grfExtra )
  153. {
  154. hr = pshlink->Resolve( (SLR_NO_UI & dwSLR) ? NULL : GetDesktopWindow(),
  155. (dwTimeout<<16) | dwSLR | SLR_ANY_MATCH );
  156. }
  157. else
  158. {
  159. hr = pshlink->QueryInterface( IID_ISLTracker, (void**) &ptracker );
  160. if( FAILED(hr) )
  161. {
  162. TrkLog((TRKDBG_ERROR, TEXT("Couldn't QI for ISLTracker")));
  163. TrkRaiseException( hr );
  164. }
  165. if( EXTRAFLAG_SHOW_IDS & grfExtra )
  166. DisplayIDs( ptracker );
  167. hr = ptracker->Resolve( GetDesktopWindow(), (dwTimeout<<16) | dwSLR | SLR_ANY_MATCH, r );
  168. if( EXTRAFLAG_SHOW_IDS & grfExtra )
  169. DisplayIDs( ptracker );
  170. }
  171. pshlink->GetPath( wszPath, cbPath, &fd, 0 );
  172. wprintf( L"%s %08X %s\n",
  173. wszPath, hr, GetRestrict(r) );
  174. RELEASE_INTERFACE( ptracker );
  175. }
  176. __except( BreakOnDebuggableException() )
  177. {
  178. RELEASE_INTERFACE( pPersistFile );
  179. RELEASE_INTERFACE( ptracker );
  180. }
  181. }
  182. BOOL
  183. DltAdminLink( ULONG cArgs, TCHAR * const rgptszArgs[], ULONG *pcEaten )
  184. {
  185. BOOL fSuccess = FALSE;
  186. HRESULT hr;
  187. CMachineId mcid(MCID_LOCAL);
  188. DWORD r = TRK_MEND_DEFAULT;
  189. DWORD grfExtra = 0;
  190. DWORD dwTimeout = 0;
  191. DWORD dwSLR = 0; // SLR_ flags
  192. IShellLink *pshlink = NULL;
  193. WCHAR wszFullPath[ MAX_PATH + 1 ];
  194. DWORD dwMoveFlags = MOVEFILE_FAIL_IF_NOT_TRACKABLE |
  195. MOVEFILE_COPY_ALLOWED |
  196. MOVEFILE_REPLACE_EXISTING;
  197. *pcEaten = 0;
  198. if( 0 == cArgs
  199. ||
  200. rgptszArgs[0][0] != TEXT('-') && rgptszArgs[0][0] != TEXT('/') )
  201. {
  202. printf( "Invalid parameters. Use -? for usage info\n" );
  203. *pcEaten = 0;
  204. goto Exit;
  205. }
  206. else if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
  207. {
  208. printf( "\nOption Link\n"
  209. " Purpose: Create/resolve a shell link\n"
  210. " Usage: -link [operation]\n"
  211. " E.g.: -link -c LinkClient LinkSource\n"
  212. " -link -r LinkClient\n"
  213. " -link -rd LinkClient\n" );
  214. printf( " Operations:\n" );
  215. printf( " Operation Params\n");
  216. printf( " --------- ------\n");
  217. printf( " CreateLink -c <link> <src>\n");
  218. printf( " ResolveLink -r<opts> <link>\n");
  219. printf( " where <opts> may use:\n" );
  220. printf( " -l = don't use log\n");
  221. printf( " -d = don't use dc\n");
  222. printf( " -i = don't use volids\n");
  223. printf( " -m = don't scan all volumes on a machine\n");
  224. printf( " -s = no search (SLR_NOSEARCH)\n");
  225. printf( " -t = no track (SLR_NOTRACK)\n");
  226. printf( " -x = show before/after droids\n");
  227. printf( " -u = no UI (SLR_NOUI)\n");
  228. printf( " -w(#)\n");
  229. printf( " = Timeout (wait) seconds on IShellLink::Resolve\n");
  230. printf( " -z = sleep in CTrkWksSvc::Mend\n");
  231. *pcEaten = 1;
  232. fSuccess = TRUE;
  233. goto Exit;
  234. }
  235. hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLink, (void**)&pshlink );
  236. if( FAILED(hr) )
  237. {
  238. printf( "Couldn't get an IShellLink (%08x)\n", hr );
  239. goto Exit;
  240. }
  241. switch (rgptszArgs[0][1])
  242. {
  243. case TEXT('c'):
  244. case TEXT('C'):
  245. if( 3 <= cArgs )
  246. {
  247. *pcEaten = 3;
  248. if( MAX_PATH < RtlGetFullPathName_U( rgptszArgs[2],
  249. sizeof(wszFullPath),
  250. wszFullPath, NULL ))
  251. {
  252. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't get full path name") ));
  253. goto Exit;
  254. }
  255. DoCreateLink( pshlink, rgptszArgs[1], wszFullPath );
  256. }
  257. break;
  258. case TEXT('r'):
  259. case TEXT('R'):
  260. if( 2 <= cArgs )
  261. {
  262. *pcEaten = 2;
  263. for( int i = 2; rgptszArgs[0][i] != TEXT('\0'); i++ )
  264. {
  265. switch(rgptszArgs[0][i])
  266. {
  267. case TEXT('l'):
  268. case TEXT('L'):
  269. r |= TRK_MEND_DONT_USE_LOG;
  270. break;
  271. case TEXT('d'):
  272. case TEXT('D'):
  273. r |= TRK_MEND_DONT_USE_DC;
  274. break;
  275. case TEXT('i'):
  276. case TEXT('I'):
  277. r |= TRK_MEND_DONT_USE_VOLIDS;
  278. break;
  279. case TEXT('m'):
  280. case TEXT('M'):
  281. r |= TRK_MEND_DONT_SEARCH_ALL_VOLUMES;
  282. break;
  283. case TEXT('s'):
  284. case TEXT('S'):
  285. dwSLR |= SLR_NOSEARCH;
  286. break;
  287. case TEXT('t'):
  288. case TEXT('T'):
  289. dwSLR |= SLR_NOTRACK;
  290. break;
  291. case TEXT('u'):
  292. case TEXT('U'):
  293. dwSLR |= SLR_NO_UI;
  294. break;
  295. case TEXT('x'):
  296. case TEXT('X'):
  297. grfExtra |= EXTRAFLAG_SHOW_IDS;
  298. break;
  299. case TEXT('z'):
  300. case TEXT('Z'):
  301. r |= TRK_MEND_SLEEP_DURING_MEND;
  302. break;
  303. case TEXT('w'):
  304. case TEXT('W'):
  305. // e.g. -link -rw(30)m
  306. if( TEXT('(') == rgptszArgs[0][i+1] )
  307. {
  308. TCHAR *ptc = _tcschr( &rgptszArgs[0][i], TEXT(')') );
  309. if( NULL != ptc )
  310. {
  311. if( 1 == _stscanf( &rgptszArgs[0][i+1], TEXT("(%d)"), &dwTimeout ))
  312. {
  313. dwTimeout *= 1000; // => milliseconds
  314. i = ( (BYTE*) ptc - (BYTE*) rgptszArgs[0] ) / sizeof(TCHAR);
  315. break;
  316. }
  317. }
  318. }
  319. default:
  320. _tprintf( TEXT("Bad Resolve switch: %c\n"), rgptszArgs[0][i] );
  321. goto Exit;
  322. } // switch
  323. } // for
  324. DoResolveLink( pshlink, rgptszArgs[1], r, dwSLR, grfExtra, dwTimeout );
  325. }
  326. break;
  327. default:
  328. _tprintf( TEXT("Invalid Link option: %c\n"), rgptszArgs[0][1] );
  329. *pcEaten = 1;
  330. break;
  331. }
  332. Exit:
  333. RELEASE_INTERFACE( pshlink );
  334. return( fSuccess );
  335. }