windows-nt/Source/XPSP1/NT/shell/osshell/tools/lnkdump/lnkdump.c

522 lines
20 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include <lnkdump.h>
#pragma hdrstop
void ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode )
{
USHORT cch;
DWORD dwBytesRead;
*lpVoid = NULL;
if (bUnicode)
{
LPWSTR lpWStr = NULL;
if (ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ))
{
lpWStr = (LPWSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1)*sizeof(WCHAR) );
if (lpWStr) {
if (ReadFile( hFile, (LPVOID)lpWStr, cch*sizeof(WCHAR), &dwBytesRead, NULL ))
{
lpWStr[cch] = L'\0';
*lpVoid = lpWStr;
}
}
}
}
else
{
LPSTR lpStr = NULL;
if (ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ))
{
lpStr = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1) );
if (lpStr) {
if (ReadFile( hFile, (LPVOID)lpStr, cch, &dwBytesRead, NULL ))
{
lpStr[cch] = '\0';
*lpVoid = lpStr;
}
}
}
}
}
int __cdecl main( int argc, char *argv[])
{
HANDLE hFile;
CShellLink csl;
CShellLink * this = &csl;
DWORD cbSize, cbTotal, cbToRead, dwBytesRead;
SYSTEMTIME st;
LPSTR pTemp = NULL;
this->pidl = 0;
this->pli = NULL;
memset( this, 0, sizeof(CShellLink) );
if (argc!=2)
{
printf("usage: lnkdump filename.lnk\n" );
return(1);
}
// Try to open the file
hFile = CreateFile( argv[1],
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
printf( "lnkdump: unable to open file %s, err %d\n",
argv[1],
GetLastError()
);
return(1);
}
// Now, read out data...
if (!ReadFile( hFile, (LPVOID)&this->sld, sizeof(this->sld), &dwBytesRead, NULL ))
return (1);
// read all of the members
if (this->sld.dwFlags & SLDF_HAS_ID_LIST)
{
// Read the size of the IDLIST
cbSize = 0; // need to zero out to get HIWORD 0 'cause USHORT is only 2 bytes
if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(USHORT), &dwBytesRead, NULL ))
return (1);
if (cbSize)
{
SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
}
else
{
printf( "Error readling PIDL out of link!\n" );
return( 1 );
}
}
// REARCHITECT: this part is not unicode ready, talk to daviddi
if (this->sld.dwFlags & (SLDF_HAS_LINK_INFO))
{
LPVOID pli;
if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ))
return (1);
if (cbSize >= sizeof(cbSize))
{
cbSize -= sizeof(cbSize);
SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
}
}
if (this->sld.dwFlags & SLDF_HAS_NAME)
ReadString( hFile, &this->pszName, this->sld.dwFlags & SLDF_UNICODE);
if (this->sld.dwFlags & SLDF_HAS_RELPATH)
ReadString( hFile, &this->pszRelPath, this->sld.dwFlags & SLDF_UNICODE);
if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR)
ReadString( hFile, &this->pszWorkingDir, this->sld.dwFlags & SLDF_UNICODE);
if (this->sld.dwFlags & SLDF_HAS_ARGS)
ReadString( hFile, &this->pszArgs, this->sld.dwFlags & SLDF_UNICODE);
if (this->sld.dwFlags & SLDF_HAS_ICONLOCATION)
ReadString( hFile, &this->pszIconLocation, this->sld.dwFlags & SLDF_UNICODE);
// Read in extra data sections
this->pExtraData = NULL;
cbTotal = 0;
while (TRUE)
{
LPSTR pReadData = NULL;
cbSize = 0;
if (!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ))
return (1);
if (cbSize < sizeof(cbSize))
break;
if (pTemp)
{
pTemp = (void *)HeapReAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
this->pExtraData,
cbTotal + cbSize + sizeof(DWORD)
);
if (pTemp)
{
this->pExtraData = (LPDBLIST)pTemp;
}
}
else
{
(LPVOID)this->pExtraData = pTemp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbTotal + cbSize + sizeof(DWORD) );
}
if (!pTemp)
break;
cbToRead = cbSize - sizeof(cbSize);
pReadData = pTemp + cbTotal;
if (!ReadFile( hFile, (LPVOID)(pReadData + sizeof(cbSize)), cbToRead, &dwBytesRead, NULL ))
return (1);
if (dwBytesRead==cbToRead)
{
// got all of the extra data, comit it
*((UNALIGNED DWORD *)pReadData) = cbSize;
cbTotal += cbSize;
}
else
break;
}
printf( "\n===== Dump of link file (%s) =====\n\n", argv[1] );
printf( "[Shell Link Data (sld)]\n" );
printf( " cbSize = 0x%08X\n", this->sld.cbSize );
printf( " GUID = {%08lX-%04X-%04X-%02X%02X-%02X%02X%02x%02x%02x%02x}\n",
this->sld.clsid.Data1, this->sld.clsid.Data2, this->sld.clsid.Data3,
this->sld.clsid.Data4[0], this->sld.clsid.Data4[1],
this->sld.clsid.Data4[2], this->sld.clsid.Data4[3],
this->sld.clsid.Data4[4], this->sld.clsid.Data4[5],
this->sld.clsid.Data4[6], this->sld.clsid.Data4[7]
);
printf( " dwFlags = 0x%08X\n", this->sld.dwFlags );
if (this->sld.dwFlags & SLDF_HAS_ID_LIST)
printf( " SLDF_HAS_ID_LIST is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_LINK_INFO)
printf( " SLDF_HAS_LINK_INFO is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_NAME)
printf( " SLDF_HAS_NAME is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_RELPATH)
printf( " SLDF_HAS_RELPATH is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR)
printf( " SLDF_HAS_WORKINGDIR is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_ARGS)
printf( " SLDF_HAS_ARGS is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_ICONLOCATION)
printf( " SLDF_HAS_ICONLOCATION is set.\n" );
if (this->sld.dwFlags & SLDF_HAS_EXP_SZ)
printf( " SLDF_HAS_EXP_SZ is set.\n" );
if (this->sld.dwFlags & SLDF_RUN_IN_SEPARATE)
printf( " SLDF_RUN_IN_SEPARATE is set.\n" );
if (this->sld.dwFlags & SLDF_UNICODE)
printf( " SLDF_HAS_UNICODE is set.\n" );
if (this->sld.dwFlags & SLDF_FORCE_NO_LINKINFO)
printf( " SLDF_FORCE_NO_LINKINFO is set.\n" );
printf( " dwFileAttributes = 0x%08X\n", this->sld.dwFileAttributes );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
printf( " FILE_ATTRIBUTE_READONLY is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
printf( " FILE_ATTRIBUTE_HIDDEN is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
printf( " FILE_ATTRIBUTE_SYSTEM is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
printf( " FILE_ATTRIBUTE_DIRECTORY is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
printf( " FILE_ATTRIBUTE_ARCHIVE is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
printf( " FILE_ATTRIBUTE_NORMAL is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)
printf( " FILE_ATTRIBUTE_TEMPORARY is set.\n" );
if (this->sld.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
printf( " FILE_ATTRIBUTE_COMPRESSED is set.\n" );
FileTimeToSystemTime( &this->sld.ftCreationTime, &st );
printf(" ftCreationTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
FileTimeToSystemTime( &this->sld.ftLastAccessTime, &st );
printf(" ftLastAccessTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
FileTimeToSystemTime( &this->sld.ftLastWriteTime, &st );
printf(" ftLastWriteTime = %02d:%02d:%02d, %02d/%02d/%04d\n", st.wHour, st.wMinute, st.wSecond, st.wMonth, st.wDay, st.wYear );
printf(" nFileSizeLow = %d bytes\n", this->sld.nFileSizeLow );
printf(" iIcon = %d\n", this->sld.iIcon );
printf(" wHotkey = 0x08%X\n", this->sld.wHotkey );
printf(" dwRes1 = 0x08%X\n", this->sld.dwRes1 );
printf(" dwRes2 = 0x08%X\n", this->sld.dwRes2 );
printf("\n[Strings]\n");
if (this->pszName)
{
printf( " pszName = " );
if (this->sld.dwFlags & SLDF_UNICODE)
{
CHAR szTemp[ 256 ];
WideCharToMultiByte( CP_ACP, 0,
(LPWSTR)this->pszName,
-1,
szTemp,
256,
NULL,
NULL
);
printf( "(UNICODE) %s\n", szTemp );
}
else
printf( "%s\n", (LPSTR)this->pszName );
}
if (this->pszRelPath)
{
printf( " pszRelPath = " );
if (this->sld.dwFlags & SLDF_UNICODE)
{
CHAR szTemp[ 256 ];
WideCharToMultiByte( CP_ACP, 0,
(LPWSTR)this->pszRelPath,
-1,
szTemp,
256,
NULL,
NULL
);
printf( "(UNICODE) %s\n", szTemp );
}
else
printf( "%s\n", (LPSTR)this->pszRelPath );
}
if (this->pszWorkingDir)
{
printf( " pszWorkingDir = " );
if (this->sld.dwFlags & SLDF_UNICODE)
{
CHAR szTemp[ 256 ];
WideCharToMultiByte( CP_ACP, 0,
(LPWSTR)this->pszWorkingDir,
-1,
szTemp,
256,
NULL,
NULL
);
printf( "(UNICODE) %s\n", szTemp );
}
else
printf( "%s\n", (LPSTR)this->pszWorkingDir );
}
if (this->pszArgs)
{
printf( " pszArgs = " );
if (this->sld.dwFlags & SLDF_UNICODE)
{
CHAR szTemp[ 256 ];
WideCharToMultiByte( CP_ACP, 0,
(LPWSTR)this->pszArgs,
-1,
szTemp,
256,
NULL,
NULL
);
printf( "(UNICODE) %s\n", szTemp );
}
else
printf( "%s\n", (LPSTR)this->pszArgs );
}
if (this->pszIconLocation)
{
printf( " pszIconLocation = " );
if (this->sld.dwFlags & SLDF_UNICODE)
{
CHAR szTemp[ 256 ];
WideCharToMultiByte( CP_ACP, 0,
(LPWSTR)this->pszIconLocation,
-1,
szTemp,
256,
NULL,
NULL
);
printf( "(UNICODE) %s\n", szTemp );
}
else
printf( "%s\n", (LPSTR)this->pszIconLocation );
}
if (this->pExtraData)
{
LPEXP_SZ_LINK lpData = (LPEXP_SZ_LINK)this->pExtraData;
while( lpData && lpData->cbSize!=0 )
{
switch( lpData->dwSignature )
{
case EXP_SZ_LINK_SIG:
{
CHAR szTemp[ 256 ];
printf("\n[Extra Data -- EXP_SZ_LINK_SIG info]\n");
printf(" cbSize = 0x%X bytes\n", lpData->cbSize );
printf(" dwSignature = 0x%X\n", lpData->dwSignature );
printf(" szTarget = %s\n", lpData->szTarget );
WideCharToMultiByte( CP_ACP, 0, lpData->swzTarget, -1, szTemp, 256, NULL, NULL );
printf(" swzTarget = (UNICODE) %s\n\n", szTemp );
}
break;
case NT_CONSOLE_PROPS_SIG:
{
CHAR szTemp[ 256 ];
INT i;
LPNT_CONSOLE_PROPS lpConData = (LPNT_CONSOLE_PROPS)lpData;
printf("\n[Extra Data -- NT_CONSOLE_PROPS_SIG info]\n");
printf(" cbSize = 0x%X bytes\n", lpConData->cbSize );
printf(" dwSignature = 0x%X\n", lpConData->dwSignature );
printf(" wFillAttribute = 0x%04X\n", lpConData->wFillAttribute );
printf(" wPopupFillAttribute = 0x%04X\n", lpConData->wPopupFillAttribute );
printf(" dwScreenBufferSize = (%d , %d)\n", lpConData->dwScreenBufferSize.X, lpConData->dwScreenBufferSize.Y );
printf(" dwWindowSize = (%d , %d)\n", lpConData->dwWindowSize.X, lpConData->dwWindowSize.Y );
printf(" dwWindowOrigin = (%d , %d)\n", lpConData->dwWindowOrigin.X, lpConData->dwWindowOrigin.Y );
printf(" nFont = %d\n", lpConData->nFont );
printf(" nInputBufferSize = %d\n", lpConData->nInputBufferSize );
printf(" dwFontSize = (%d , %d)\n", lpConData->dwFontSize.X, lpConData->dwFontSize.Y );
printf(" uFontFamily = 0x%08X\n", lpConData->uFontFamily );
printf(" uFontWeight = 0x%08X\n", lpConData->uFontWeight );
WideCharToMultiByte( CP_ACP, 0, lpConData->FaceName, LF_FACESIZE, szTemp, LF_FACESIZE, NULL, NULL );
szTemp[ LF_FACESIZE ] = (CHAR)0;
printf(" FaceName = %s\n", szTemp );
printf(" uCursorSize = %d\n", lpConData->uCursorSize );
printf(" bFullScreen = %s\n", lpConData->bFullScreen ? "TRUE" : "FALSE" );
printf(" bQuickEdit = %s\n", lpConData->bQuickEdit ? "TRUE" : "FALSE" );
printf(" bInsertMode = %s\n", lpConData->bInsertMode ? "TRUE" : "FALSE" );
printf(" bAutoPosition = %s\n", lpConData->bAutoPosition ? "TRUE" : "FALSE" );
printf(" uHistoryBufferSize = %d\n", lpConData->uHistoryBufferSize );
printf(" uNumHistoryBuffers = %d\n", lpConData->uNumberOfHistoryBuffers );
printf(" bHistoryNoDup = %s\n", lpConData->bHistoryNoDup ? "TRUE" : "FALSE" );
printf(" ColorTable = [" );
i=0;
while( i < 16 )
{
printf("\n ");
printf("0x%08X ", lpConData->ColorTable[i++]);
printf("0x%08X ", lpConData->ColorTable[i++]);
printf("0x%08X ", lpConData->ColorTable[i++]);
printf("0x%08X ", lpConData->ColorTable[i++]);
}
printf( "]\n\n" );
}
break;
case NT_FE_CONSOLE_PROPS_SIG:
{
LPNT_FE_CONSOLE_PROPS lpFEConData = (LPNT_FE_CONSOLE_PROPS)lpData;
printf("\n[Extra Data -- NT_FE_CONSOLE_PROPS_SIG info]\n");
printf(" cbSize = 0x%X bytes\n", lpFEConData->cbSize );
printf(" dwSignature = 0x%X\n", lpFEConData->dwSignature );
printf(" CodePage = %d\n\n", lpFEConData->uCodePage );
}
break;
case EXP_DARWIN_ID_SIG:
{
CHAR szTemp[ 256 ];
LPEXP_DARWIN_LINK lpDarwin = (LPEXP_DARWIN_LINK)lpData;
printf("\n[Extra Data -- EXP_DARWIN_ID_SIG info]\n");
printf(" szDarwinID = %s\n", lpDarwin->szDarwinID );
WideCharToMultiByte( CP_ACP, 0, lpDarwin->szwDarwinID, -1, szTemp, 256, NULL, NULL );
printf(" szwDarwinID = (UNICODE) %s\n\n", szTemp );
}
break;
case EXP_SPECIAL_FOLDER_SIG:
{
LPEXP_SPECIAL_FOLDER lpFolder = (LPEXP_SPECIAL_FOLDER)lpData;
printf("\n[Extra Data -- EXP_SPECIAL_FOLDER_SIG info]\n");
printf(" idSpecialFolder = 0x%X\n", lpFolder->idSpecialFolder );
printf(" cbOffset = 0x%X\n\n", lpFolder->cbOffset );
}
break;
#ifdef WINNT
case EXP_TRACKER_SIG:
{
LPEXP_TRACKER lpTracker = (LPEXP_TRACKER)lpData;
WCHAR wszGUID[ MAX_PATH ];
printf("\n[Extra Data -- EXP_TRACKER_SIG info]\n");
#if 0
// (reinerf) - traker info looks like a byte-array, how do we dump it?
printf(" abTracker = 0x%X\n", lpTracker->abTracker);
#endif
}
#endif
break;
case EXP_SZ_ICON_SIG:
{
CHAR szTemp[256];
LPEXP_SZ_LINK lpExpIcon = (LPEXP_SZ_LINK)lpData;
printf("\n[Extra Data -- EXP_SZ_ICON_SIG info]\n");
printf(" szTarget = %s\n", lpExpIcon->szTarget );
WideCharToMultiByte( CP_ACP, 0, lpExpIcon->swzTarget, -1, szTemp, 256, NULL, NULL );
printf(" wszTarget = (UNICODE) %s\n\n", szTemp );
}
break;
} // end swtich
(LPBYTE)lpData += lpData->cbSize;
}
LocalFree( this->pExtraData );
}
if (this->pidl)
LocalFree( (HLOCAL)this->pidl );
if (this->pli)
LocalFree( this->pli );
if (this->pszName)
HeapFree( GetProcessHeap(), 0, this->pszName );
if (this->pszRelPath)
HeapFree( GetProcessHeap(), 0, this->pszRelPath );
if (this->pszWorkingDir)
HeapFree( GetProcessHeap(), 0, this->pszWorkingDir );
if (this->pszArgs)
HeapFree( GetProcessHeap(), 0, this->pszArgs );
if (this->pszIconLocation)
HeapFree( GetProcessHeap(), 0, this->pszIconLocation );
return(0);
}