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.

521 lines
20 KiB

  1. #include <lnkdump.h>
  2. #pragma hdrstop
  3. void ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode )
  4. {
  5. USHORT cch;
  6. DWORD dwBytesRead;
  7. *lpVoid = NULL;
  8. if (bUnicode)
  9. {
  10. LPWSTR lpWStr = NULL;
  11. if (ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ))
  12. {
  13. lpWStr = (LPWSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1)*sizeof(WCHAR) );
  14. if (lpWStr) {
  15. if (ReadFile( hFile, (LPVOID)lpWStr, cch*sizeof(WCHAR), &dwBytesRead, NULL ))
  16. {
  17. lpWStr[cch] = L'\0';
  18. *lpVoid = lpWStr;
  19. }
  20. }
  21. }
  22. }
  23. else
  24. {
  25. LPSTR lpStr = NULL;
  26. if (ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ))
  27. {
  28. lpStr = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1) );
  29. if (lpStr) {
  30. if (ReadFile( hFile, (LPVOID)lpStr, cch, &dwBytesRead, NULL ))
  31. {
  32. lpStr[cch] = '\0';
  33. *lpVoid = lpStr;
  34. }
  35. }
  36. }
  37. }
  38. }
  39. int __cdecl main( int argc, char *argv[])
  40. {
  41. HANDLE hFile;
  42. CShellLink csl;
  43. CShellLink * this = &csl;
  44. DWORD cbSize, cbTotal, cbToRead, dwBytesRead;
  45. SYSTEMTIME st;
  46. LPSTR pTemp = NULL;
  47. this->pidl = 0;
  48. this->pli = NULL;
  49. memset( this, 0, sizeof(CShellLink) );
  50. if (argc!=2)
  51. {
  52. printf("usage: lnkdump filename.lnk\n" );
  53. return(1);
  54. }
  55. // Try to open the file
  56. hFile = CreateFile( argv[1],
  57. GENERIC_READ,
  58. FILE_SHARE_READ,
  59. NULL,
  60. OPEN_EXISTING,
  61. FILE_ATTRIBUTE_NORMAL,
  62. NULL
  63. );
  64. if (hFile == INVALID_HANDLE_VALUE)
  65. {
  66. printf( "lnkdump: unable to open file %s, err %d\n",
  67. argv[1],
  68. GetLastError()
  69. );
  70. return(1);
  71. }
  72. // Now, read out data...
  73. if (!ReadFile( hFile, (LPVOID)&this->sld, sizeof(this->sld), &dwBytesRead, NULL ))
  74. return (1);
  75. // read all of the members
  76. if (this->sld.dwFlags & SLDF_HAS_ID_LIST)
  77. {
  78. // Read the size of the IDLIST
  79. cbSize = 0; // need to zero out to get HIWORD 0 'cause USHORT is only 2 bytes
  80. if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(USHORT), &dwBytesRead, NULL ))
  81. return (1);
  82. if (cbSize)
  83. {
  84. SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
  85. }
  86. else
  87. {
  88. printf( "Error readling PIDL out of link!\n" );
  89. return( 1 );
  90. }
  91. }
  92. // REARCHITECT: this part is not unicode ready, talk to daviddi
  93. if (this->sld.dwFlags & (SLDF_HAS_LINK_INFO))
  94. {
  95. LPVOID pli;
  96. if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ))
  97. return (1);
  98. if (cbSize >= sizeof(cbSize))
  99. {
  100. cbSize -= sizeof(cbSize);
  101. SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
  102. }
  103. }
  104. if (this->sld.dwFlags & SLDF_HAS_NAME)
  105. ReadString( hFile, &this->pszName, this->sld.dwFlags & SLDF_UNICODE);
  106. if (this->sld.dwFlags & SLDF_HAS_RELPATH)
  107. ReadString( hFile, &this->pszRelPath, this->sld.dwFlags & SLDF_UNICODE);
  108. if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR)
  109. ReadString( hFile, &this->pszWorkingDir, this->sld.dwFlags & SLDF_UNICODE);
  110. if (this->sld.dwFlags & SLDF_HAS_ARGS)
  111. ReadString( hFile, &this->pszArgs, this->sld.dwFlags & SLDF_UNICODE);
  112. if (this->sld.dwFlags & SLDF_HAS_ICONLOCATION)
  113. ReadString( hFile, &this->pszIconLocation, this->sld.dwFlags & SLDF_UNICODE);
  114. // Read in extra data sections
  115. this->pExtraData = NULL;
  116. cbTotal = 0;
  117. while (TRUE)
  118. {
  119. LPSTR pReadData = NULL;
  120. cbSize = 0;
  121. if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ))
  122. return (1);
  123. if (cbSize < sizeof(cbSize))
  124. break;
  125. if (pTemp)
  126. {
  127. pTemp = (void *)HeapReAlloc( GetProcessHeap(),
  128. HEAP_ZERO_MEMORY,
  129. this->pExtraData,
  130. cbTotal + cbSize + sizeof(DWORD)
  131. );
  132. if (pTemp)
  133. {
  134. this->pExtraData = (LPDBLIST)pTemp;
  135. }
  136. }
  137. else
  138. {
  139. (LPVOID)this->pExtraData = pTemp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbTotal + cbSize + sizeof(DWORD) );
  140. }
  141. if (!pTemp)
  142. break;
  143. cbToRead = cbSize - sizeof(cbSize);
  144. pReadData = pTemp + cbTotal;
  145. if (!ReadFile( hFile, (LPVOID)(pReadData + sizeof(cbSize)), cbToRead, &dwBytesRead, NULL ))
  146. return (1);
  147. if (dwBytesRead==cbToRead)
  148. {
  149. // got all of the extra data, comit it
  150. *((UNALIGNED DWORD *)pReadData) = cbSize;
  151. cbTotal += cbSize;
  152. }
  153. else
  154. break;
  155. }
  156. printf( "\n===== Dump of link file (%s) =====\n\n", argv[1] );
  157. printf( "[Shell Link Data (sld)]\n" );
  158. printf( " cbSize = 0x%08X\n", this->sld.cbSize );
  159. printf( " GUID = {%08lX-%04X-%04X-%02X%02X-%02X%02X%02x%02x%02x%02x}\n",
  160. this->sld.clsid.Data1, this->sld.clsid.Data2, this->sld.clsid.Data3,
  161. this->sld.clsid.Data4[0], this->sld.clsid.Data4[1],
  162. this->sld.clsid.Data4[2], this->sld.clsid.Data4[3],
  163. this->sld.clsid.Data4[4], this->sld.clsid.Data4[5],
  164. this->sld.clsid.Data4[6], this->sld.clsid.Data4[7]
  165. );
  166. printf( " dwFlags = 0x%08X\n", this->sld.dwFlags );
  167. if (this->sld.dwFlags & SLDF_HAS_ID_LIST)
  168. printf( " SLDF_HAS_ID_LIST is set.\n" );
  169. if (this->sld.dwFlags & SLDF_HAS_LINK_INFO)
  170. printf( " SLDF_HAS_LINK_INFO is set.\n" );
  171. if (this->sld.dwFlags & SLDF_HAS_NAME)
  172. printf( " SLDF_HAS_NAME is set.\n" );
  173. if (this->sld.dwFlags & SLDF_HAS_RELPATH)
  174. printf( " SLDF_HAS_RELPATH is set.\n" );
  175. if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR)
  176. printf( " SLDF_HAS_WORKINGDIR is set.\n" );
  177. if (this->sld.dwFlags & SLDF_HAS_ARGS)
  178. printf( " SLDF_HAS_ARGS is set.\n" );
  179. if (this->sld.dwFlags & SLDF_HAS_ICONLOCATION)
  180. printf( " SLDF_HAS_ICONLOCATION is set.\n" );
  181. if (this->sld.dwFlags & SLDF_HAS_EXP_SZ)
  182. printf( " SLDF_HAS_EXP_SZ is set.\n" );
  183. if (this->sld.dwFlags & SLDF_RUN_IN_SEPARATE)
  184. printf( " SLDF_RUN_IN_SEPARATE is set.\n" );
  185. if (this->sld.dwFlags & SLDF_UNICODE)
  186. printf( " SLDF_HAS_UNICODE is set.\n" );
  187. if (this->sld.dwFlags & SLDF_FORCE_NO_LINKINFO)
  188. printf( " SLDF_FORCE_NO_LINKINFO is set.\n" );
  189. printf( " dwFileAttributes = 0x%08X\n", this->sld.dwFileAttributes );
  190. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  191. printf( " FILE_ATTRIBUTE_READONLY is set.\n" );
  192. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
  193. printf( " FILE_ATTRIBUTE_HIDDEN is set.\n" );
  194. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
  195. printf( " FILE_ATTRIBUTE_SYSTEM is set.\n" );
  196. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  197. printf( " FILE_ATTRIBUTE_DIRECTORY is set.\n" );
  198. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
  199. printf( " FILE_ATTRIBUTE_ARCHIVE is set.\n" );
  200. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
  201. printf( " FILE_ATTRIBUTE_NORMAL is set.\n" );
  202. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)
  203. printf( " FILE_ATTRIBUTE_TEMPORARY is set.\n" );
  204. if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
  205. printf( " FILE_ATTRIBUTE_COMPRESSED is set.\n" );
  206. FileTimeToSystemTime( &this->sld.ftCreationTime, &st );
  207. printf(" ftCreationTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
  208. FileTimeToSystemTime( &this->sld.ftLastAccessTime, &st );
  209. printf(" ftLastAccessTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
  210. FileTimeToSystemTime( &this->sld.ftLastWriteTime, &st );
  211. printf(" ftLastWriteTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
  212. printf(" nFileSizeLow = %d bytes\n", this->sld.nFileSizeLow );
  213. printf(" iIcon = %d\n", this->sld.iIcon );
  214. printf(" wHotkey = 0x08%X\n", this->sld.wHotkey );
  215. printf(" dwRes1 = 0x08%X\n", this->sld.dwRes1 );
  216. printf(" dwRes2 = 0x08%X\n", this->sld.dwRes2 );
  217. printf("\n[Strings]\n");
  218. if (this->pszName)
  219. {
  220. printf( " pszName = " );
  221. if (this->sld.dwFlags & SLDF_UNICODE)
  222. {
  223. CHAR szTemp[ 256 ];
  224. WideCharToMultiByte( CP_ACP, 0,
  225. (LPWSTR)this->pszName,
  226. -1,
  227. szTemp,
  228. 256,
  229. NULL,
  230. NULL
  231. );
  232. printf( "(UNICODE) %s\n", szTemp );
  233. }
  234. else
  235. printf( "%s\n", (LPSTR)this->pszName );
  236. }
  237. if (this->pszRelPath)
  238. {
  239. printf( " pszRelPath = " );
  240. if (this->sld.dwFlags & SLDF_UNICODE)
  241. {
  242. CHAR szTemp[ 256 ];
  243. WideCharToMultiByte( CP_ACP, 0,
  244. (LPWSTR)this->pszRelPath,
  245. -1,
  246. szTemp,
  247. 256,
  248. NULL,
  249. NULL
  250. );
  251. printf( "(UNICODE) %s\n", szTemp );
  252. }
  253. else
  254. printf( "%s\n", (LPSTR)this->pszRelPath );
  255. }
  256. if (this->pszWorkingDir)
  257. {
  258. printf( " pszWorkingDir = " );
  259. if (this->sld.dwFlags & SLDF_UNICODE)
  260. {
  261. CHAR szTemp[ 256 ];
  262. WideCharToMultiByte( CP_ACP, 0,
  263. (LPWSTR)this->pszWorkingDir,
  264. -1,
  265. szTemp,
  266. 256,
  267. NULL,
  268. NULL
  269. );
  270. printf( "(UNICODE) %s\n", szTemp );
  271. }
  272. else
  273. printf( "%s\n", (LPSTR)this->pszWorkingDir );
  274. }
  275. if (this->pszArgs)
  276. {
  277. printf( " pszArgs = " );
  278. if (this->sld.dwFlags & SLDF_UNICODE)
  279. {
  280. CHAR szTemp[ 256 ];
  281. WideCharToMultiByte( CP_ACP, 0,
  282. (LPWSTR)this->pszArgs,
  283. -1,
  284. szTemp,
  285. 256,
  286. NULL,
  287. NULL
  288. );
  289. printf( "(UNICODE) %s\n", szTemp );
  290. }
  291. else
  292. printf( "%s\n", (LPSTR)this->pszArgs );
  293. }
  294. if (this->pszIconLocation)
  295. {
  296. printf( " pszIconLocation = " );
  297. if (this->sld.dwFlags & SLDF_UNICODE)
  298. {
  299. CHAR szTemp[ 256 ];
  300. WideCharToMultiByte( CP_ACP, 0,
  301. (LPWSTR)this->pszIconLocation,
  302. -1,
  303. szTemp,
  304. 256,
  305. NULL,
  306. NULL
  307. );
  308. printf( "(UNICODE) %s\n", szTemp );
  309. }
  310. else
  311. printf( "%s\n", (LPSTR)this->pszIconLocation );
  312. }
  313. if (this->pExtraData)
  314. {
  315. LPEXP_SZ_LINK lpData = (LPEXP_SZ_LINK)this->pExtraData;
  316. while( lpData && lpData->cbSize!=0 )
  317. {
  318. switch( lpData->dwSignature )
  319. {
  320. case EXP_SZ_LINK_SIG:
  321. {
  322. CHAR szTemp[ 256 ];
  323. printf("\n[Extra Data -- EXP_SZ_LINK_SIG info]\n");
  324. printf(" cbSize = 0x%X bytes\n", lpData->cbSize );
  325. printf(" dwSignature = 0x%X\n", lpData->dwSignature );
  326. printf(" szTarget = %s\n", lpData->szTarget );
  327. WideCharToMultiByte( CP_ACP, 0, lpData->swzTarget, -1, szTemp, 256, NULL, NULL );
  328. printf(" swzTarget = (UNICODE) %s\n\n", szTemp );
  329. }
  330. break;
  331. case NT_CONSOLE_PROPS_SIG:
  332. {
  333. CHAR szTemp[ 256 ];
  334. INT i;
  335. LPNT_CONSOLE_PROPS lpConData = (LPNT_CONSOLE_PROPS)lpData;
  336. printf("\n[Extra Data -- NT_CONSOLE_PROPS_SIG info]\n");
  337. printf(" cbSize = 0x%X bytes\n", lpConData->cbSize );
  338. printf(" dwSignature = 0x%X\n", lpConData->dwSignature );
  339. printf(" wFillAttribute = 0x%04X\n", lpConData->wFillAttribute );
  340. printf(" wPopupFillAttribute = 0x%04X\n", lpConData->wPopupFillAttribute );
  341. printf(" dwScreenBufferSize = (%d , %d)\n", lpConData->dwScreenBufferSize.X, lpConData->dwScreenBufferSize.Y );
  342. printf(" dwWindowSize = (%d , %d)\n", lpConData->dwWindowSize.X, lpConData->dwWindowSize.Y );
  343. printf(" dwWindowOrigin = (%d , %d)\n", lpConData->dwWindowOrigin.X, lpConData->dwWindowOrigin.Y );
  344. printf(" nFont = %d\n", lpConData->nFont );
  345. printf(" nInputBufferSize = %d\n", lpConData->nInputBufferSize );
  346. printf(" dwFontSize = (%d , %d)\n", lpConData->dwFontSize.X, lpConData->dwFontSize.Y );
  347. printf(" uFontFamily = 0x%08X\n", lpConData->uFontFamily );
  348. printf(" uFontWeight = 0x%08X\n", lpConData->uFontWeight );
  349. WideCharToMultiByte( CP_ACP, 0, lpConData->FaceName, LF_FACESIZE, szTemp, LF_FACESIZE, NULL, NULL );
  350. szTemp[ LF_FACESIZE ] = (CHAR)0;
  351. printf(" FaceName = %s\n", szTemp );
  352. printf(" uCursorSize = %d\n", lpConData->uCursorSize );
  353. printf(" bFullScreen = %s\n", lpConData->bFullScreen ? "TRUE" : "FALSE" );
  354. printf(" bQuickEdit = %s\n", lpConData->bQuickEdit ? "TRUE" : "FALSE" );
  355. printf(" bInsertMode = %s\n", lpConData->bInsertMode ? "TRUE" : "FALSE" );
  356. printf(" bAutoPosition = %s\n", lpConData->bAutoPosition ? "TRUE" : "FALSE" );
  357. printf(" uHistoryBufferSize = %d\n", lpConData->uHistoryBufferSize );
  358. printf(" uNumHistoryBuffers = %d\n", lpConData->uNumberOfHistoryBuffers );
  359. printf(" bHistoryNoDup = %s\n", lpConData->bHistoryNoDup ? "TRUE" : "FALSE" );
  360. printf(" ColorTable = [" );
  361. i=0;
  362. while( i < 16 )
  363. {
  364. printf("\n ");
  365. printf("0x%08X ", lpConData->ColorTable[i++]);
  366. printf("0x%08X ", lpConData->ColorTable[i++]);
  367. printf("0x%08X ", lpConData->ColorTable[i++]);
  368. printf("0x%08X ", lpConData->ColorTable[i++]);
  369. }
  370. printf( "]\n\n" );
  371. }
  372. break;
  373. case NT_FE_CONSOLE_PROPS_SIG:
  374. {
  375. LPNT_FE_CONSOLE_PROPS lpFEConData = (LPNT_FE_CONSOLE_PROPS)lpData;
  376. printf("\n[Extra Data -- NT_FE_CONSOLE_PROPS_SIG info]\n");
  377. printf(" cbSize = 0x%X bytes\n", lpFEConData->cbSize );
  378. printf(" dwSignature = 0x%X\n", lpFEConData->dwSignature );
  379. printf(" CodePage = %d\n\n", lpFEConData->uCodePage );
  380. }
  381. break;
  382. case EXP_DARWIN_ID_SIG:
  383. {
  384. CHAR szTemp[ 256 ];
  385. LPEXP_DARWIN_LINK lpDarwin = (LPEXP_DARWIN_LINK)lpData;
  386. printf("\n[Extra Data -- EXP_DARWIN_ID_SIG info]\n");
  387. printf(" szDarwinID = %s\n", lpDarwin->szDarwinID );
  388. WideCharToMultiByte( CP_ACP, 0, lpDarwin->szwDarwinID, -1, szTemp, 256, NULL, NULL );
  389. printf(" szwDarwinID = (UNICODE) %s\n\n", szTemp );
  390. }
  391. break;
  392. case EXP_SPECIAL_FOLDER_SIG:
  393. {
  394. LPEXP_SPECIAL_FOLDER lpFolder = (LPEXP_SPECIAL_FOLDER)lpData;
  395. printf("\n[Extra Data -- EXP_SPECIAL_FOLDER_SIG info]\n");
  396. printf(" idSpecialFolder = 0x%X\n", lpFolder->idSpecialFolder );
  397. printf(" cbOffset = 0x%X\n\n", lpFolder->cbOffset );
  398. }
  399. break;
  400. #ifdef WINNT
  401. case EXP_TRACKER_SIG:
  402. {
  403. LPEXP_TRACKER lpTracker = (LPEXP_TRACKER)lpData;
  404. WCHAR wszGUID[ MAX_PATH ];
  405. printf("\n[Extra Data -- EXP_TRACKER_SIG info]\n");
  406. #if 0
  407. // (reinerf) - traker info looks like a byte-array, how do we dump it?
  408. printf(" abTracker = 0x%X\n", lpTracker->abTracker);
  409. #endif
  410. }
  411. #endif
  412. break;
  413. case EXP_SZ_ICON_SIG:
  414. {
  415. CHAR szTemp[256];
  416. LPEXP_SZ_LINK lpExpIcon = (LPEXP_SZ_LINK)lpData;
  417. printf("\n[Extra Data -- EXP_SZ_ICON_SIG info]\n");
  418. printf(" szTarget = %s\n", lpExpIcon->szTarget );
  419. WideCharToMultiByte( CP_ACP, 0, lpExpIcon->swzTarget, -1, szTemp, 256, NULL, NULL );
  420. printf(" wszTarget = (UNICODE) %s\n\n", szTemp );
  421. }
  422. break;
  423. } // end swtich
  424. (LPBYTE)lpData += lpData->cbSize;
  425. }
  426. LocalFree( this->pExtraData );
  427. }
  428. if (this->pidl)
  429. LocalFree( (HLOCAL)this->pidl );
  430. if (this->pli)
  431. LocalFree( this->pli );
  432. if (this->pszName)
  433. HeapFree( GetProcessHeap(), 0, this->pszName );
  434. if (this->pszRelPath)
  435. HeapFree( GetProcessHeap(), 0, this->pszRelPath );
  436. if (this->pszWorkingDir)
  437. HeapFree( GetProcessHeap(), 0, this->pszWorkingDir );
  438. if (this->pszArgs)
  439. HeapFree( GetProcessHeap(), 0, this->pszArgs );
  440. if (this->pszIconLocation)
  441. HeapFree( GetProcessHeap(), 0, this->pszIconLocation );
  442. return(0);
  443. }