Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

link.c

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------- 00002 // 00003 // link.c link management routines (reading, etc.) 00004 // 00005 // Copyright (c) 1985 - 1999, Microsoft Corporation 00006 // 00007 //--------------------------------------------------------------------------- 00008 00009 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 00015 DWORD 00016 GetTitleFromLinkName( 00017 IN LPWSTR szLinkName, 00018 OUT LPWSTR szTitle 00019 ) 00020 /*++ 00021 00022 Routine Description: 00023 00024 This routine returns the title (i.e., display name of the link) in szTitle, 00025 and the number of bytes (not chars) in szTitle. 00026 00027 Arguments: 00028 00029 szLinkName - fully qualified path to link file 00030 szTitle - pointer to buffer to contain title (display name) of the link 00031 00032 i.e.: 00033 "C:\nt\desktop\A Link File Name.lnk" --> "A Link File Name" 00034 00035 Return Value: 00036 00037 number of bytes copied to szTitle 00038 00039 --*/ 00040 { 00041 DWORD dwLen; 00042 LPWSTR pLnk, pDot; 00043 LPWSTR pPath = szLinkName; 00044 00045 // Error checking 00046 ASSERT(szLinkName); 00047 00048 // find filename at end of fully qualified link name and point pLnk to it 00049 for (pLnk = pPath; *pPath; pPath++) 00050 { 00051 if ( (pPath[0] == L'\\' || pPath[0] == L':') && 00052 pPath[1] && 00053 (pPath[1] != L'\\') 00054 ) 00055 pLnk = pPath + 1; 00056 } 00057 00058 // find extension (.lnk) 00059 pPath = pLnk; 00060 for (pDot = NULL; *pPath; pPath++) 00061 { 00062 switch (*pPath) { 00063 case L'.': 00064 pDot = pPath; // remember the last dot 00065 break; 00066 case L'\\': 00067 case L' ': // extensions can't have spaces 00068 pDot = NULL; // forget last dot, it was in a directory 00069 break; 00070 } 00071 } 00072 00073 // if we found the extension, pDot points to it, if not, pDot 00074 // is NULL. 00075 00076 if (pDot) 00077 { 00078 dwLen = (ULONG)((pDot - pLnk) * sizeof(WCHAR)); 00079 } 00080 else 00081 { 00082 dwLen = lstrlenW(pLnk) * sizeof(WCHAR); 00083 } 00084 dwLen = min(dwLen, MAX_TITLE_LENGTH); 00085 00086 RtlCopyMemory(szTitle, pLnk, dwLen); 00087 00088 return dwLen; 00089 } 00090 00091 00092 BOOL ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode ) 00093 { 00094 00095 USHORT cch; 00096 DWORD dwBytesRead; 00097 BOOL fResult = TRUE; 00098 00099 if (bUnicode) 00100 { 00101 LPWSTR lpWStr = NULL; 00102 00103 fResult &= ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ); 00104 lpWStr = (LPWSTR)ConsoleHeapAlloc( HEAP_ZERO_MEMORY, (cch+1)*sizeof(WCHAR) ); 00105 if (lpWStr) { 00106 fResult &= ReadFile( hFile, (LPVOID)lpWStr, cch*sizeof(WCHAR), &dwBytesRead, NULL ); 00107 lpWStr[cch] = L'\0'; 00108 } 00109 *(LPWSTR *)lpVoid = lpWStr; 00110 } 00111 else 00112 { 00113 LPSTR lpStr = NULL; 00114 00115 fResult &= ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL ); 00116 lpStr = (LPSTR)ConsoleHeapAlloc( HEAP_ZERO_MEMORY, (cch+1) ); 00117 if (lpStr) { 00118 fResult &= ReadFile( hFile, (LPVOID)lpStr, cch, &dwBytesRead, NULL ); 00119 lpStr[cch] = '\0'; 00120 } 00121 *(LPSTR *)lpVoid = lpStr; 00122 } 00123 00124 return fResult; 00125 00126 } 00127 00128 00129 BOOL LoadLink( LPWSTR pszLinkName, CShellLink * this ) 00130 { 00131 00132 HANDLE hFile; 00133 DWORD dwBytesRead, cbSize, cbTotal, cbToRead; 00134 BOOL fResult = TRUE; 00135 LPSTR pTemp = NULL; 00136 00137 // Try to open the file 00138 hFile = CreateFile( pszLinkName, 00139 GENERIC_READ, 00140 FILE_SHARE_READ, 00141 NULL, 00142 OPEN_EXISTING, 00143 FILE_ATTRIBUTE_NORMAL, 00144 NULL 00145 ); 00146 00147 if (hFile==INVALID_HANDLE_VALUE) 00148 return FALSE; 00149 00150 00151 // Now, read out data... 00152 00153 fResult = ReadFile( hFile, (LPVOID)&this->sld, sizeof(this->sld), &dwBytesRead, NULL ); 00154 fResult &= ((dwBytesRead == sizeof(this->sld)) && (this->sld.cbSize == sizeof(this->sld))); 00155 00156 // read all of the members 00157 00158 if (this->sld.dwFlags & SLDF_HAS_ID_LIST) 00159 { 00160 // Read the size of the IDLIST 00161 cbSize = 0; // need to zero out to get HIWORD 0 'cause USHORT is only 2 bytes 00162 fResult &= ReadFile( hFile, (LPVOID)&cbSize, sizeof(USHORT), &dwBytesRead, NULL ); 00163 fResult &= (dwBytesRead == sizeof(USHORT)); 00164 if (cbSize) 00165 { 00166 fResult &= 00167 (SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT)!=0xFFFFFFFF); 00168 } 00169 else 00170 { 00171 if (hFile) 00172 CloseHandle( hFile ); 00173 return FALSE; 00174 } 00175 } 00176 00177 // BUGBUG: this part is not unicode ready, talk to daviddi 00178 00179 if (this->sld.dwFlags & (SLDF_HAS_LINK_INFO)) 00180 { 00181 00182 fResult &= ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ); 00183 fResult &= (dwBytesRead == sizeof(cbSize)); 00184 if (cbSize >= sizeof(cbSize)) 00185 { 00186 cbSize -= sizeof(cbSize); 00187 fResult &= 00188 (SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT)!=0xFFFFFFFF); 00189 } 00190 00191 } 00192 00193 if (this->sld.dwFlags & SLDF_HAS_NAME) 00194 fResult &= ReadString( hFile, &this->pszName, this->sld.dwFlags & SLDF_UNICODE); 00195 if (this->sld.dwFlags & SLDF_HAS_RELPATH) 00196 fResult &= ReadString( hFile, &this->pszRelPath, this->sld.dwFlags & SLDF_UNICODE); 00197 if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR) 00198 fResult &= ReadString( hFile, &this->pszWorkingDir, this->sld.dwFlags & SLDF_UNICODE); 00199 if (this->sld.dwFlags & SLDF_HAS_ARGS) 00200 fResult &= ReadString( hFile, &this->pszArgs, this->sld.dwFlags & SLDF_UNICODE); 00201 if (this->sld.dwFlags & SLDF_HAS_ICONLOCATION) 00202 fResult &= ReadString( hFile, &this->pszIconLocation, this->sld.dwFlags & SLDF_UNICODE); 00203 00204 // Read in extra data sections 00205 this->pExtraData = NULL; 00206 cbTotal = 0; 00207 while (TRUE) 00208 { 00209 00210 LPSTR pReadData = NULL; 00211 00212 cbSize = 0; 00213 fResult &= ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL ); 00214 00215 if (cbSize < sizeof(cbSize)) 00216 break; 00217 00218 if (pTemp) 00219 { 00220 pTemp = (void *)ConsoleHeapReAlloc( 00221 HEAP_ZERO_MEMORY, 00222 this->pExtraData, 00223 cbTotal + cbSize + sizeof(DWORD) 00224 ); 00225 if (pTemp) 00226 { 00227 this->pExtraData = pTemp; 00228 } 00229 } 00230 else 00231 { 00232 this->pExtraData = pTemp = ConsoleHeapAlloc( HEAP_ZERO_MEMORY, cbTotal + cbSize + sizeof(DWORD) ); 00233 00234 } 00235 00236 if (!pTemp) 00237 break; 00238 00239 cbToRead = cbSize - sizeof(cbSize); 00240 pReadData = pTemp + cbTotal; 00241 00242 fResult &= ReadFile( hFile, (LPVOID)(pReadData + sizeof(cbSize)), cbToRead, &dwBytesRead, NULL ); 00243 if (dwBytesRead==cbToRead) 00244 { 00245 // got all of the extra data, comit it 00246 *((UNALIGNED DWORD *)pReadData) = cbSize; 00247 cbTotal += cbSize; 00248 } 00249 else 00250 break; 00251 00252 } 00253 00254 00255 if (hFile) 00256 CloseHandle( hFile ); 00257 00258 return fResult; 00259 00260 } 00261 00262 00263 00264 DWORD GetLinkProperties( LPWSTR pszLinkName, LPVOID lpvBuffer, UINT cb ) 00265 { 00266 CShellLink mld; 00267 DWORD fResult; 00268 LPNT_CONSOLE_PROPS lpExtraData; 00269 DWORD dwSize = 0; 00270 00271 /* 00272 { 00273 TCHAR szRick[ 1024 ]; 00274 STARTUPINFO si; 00275 PROCESS_INFORMATION pi; 00276 00277 // HUGE, HUGE hack-o-rama to get NTSD started on this process! 00278 wsprintf( szRick, TEXT("ntsd -d -p %d"), GetCurrentProcessId() ); 00279 GetStartupInfo( &si ); 00280 CreateProcess( NULL, szRick, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); 00281 CloseHandle( pi.hProcess ); 00282 CloseHandle( pi.hThread ); 00283 Sleep( 5*1000 ); 00284 DebugBreak(); 00285 00286 } 00287 */ 00288 00289 00290 00291 // Zero out structure on the stack 00292 RtlZeroMemory( &mld, sizeof(mld) ); 00293 00294 // Load link data 00295 if (!LoadLink( pszLinkName, &mld )) { 00296 RIPMSG1(RIP_WARNING, "LoadLink %ws failed", pszLinkName); 00297 fResult = LINK_NOINFO; 00298 goto Cleanup; 00299 } 00300 00301 // Check return buffer -- is it big enough? 00302 ASSERT(cb >= sizeof( LNKPROPNTCONSOLE)); 00303 00304 // Zero out callers buffer 00305 RtlZeroMemory( lpvBuffer, cb ); 00306 00307 // Copy relevant shell link data into caller's buffer 00308 if (mld.pszName) 00309 lstrcpy( ((LPLNKPROPNTCONSOLE)lpvBuffer)->pszName, mld.pszName ); 00310 if (mld.pszIconLocation) 00311 lstrcpy( ((LPLNKPROPNTCONSOLE)lpvBuffer)->pszIconLocation, mld.pszIconLocation ); 00312 ((LPLNKPROPNTCONSOLE)lpvBuffer)->uIcon = mld.sld.iIcon; 00313 ((LPLNKPROPNTCONSOLE)lpvBuffer)->uShowCmd = mld.sld.iShowCmd; 00314 ((LPLNKPROPNTCONSOLE)lpvBuffer)->uHotKey = mld.sld.wHotkey; 00315 fResult = LINK_SIMPLEINFO; 00316 00317 // Find console properties in extra data section 00318 for( lpExtraData = (LPNT_CONSOLE_PROPS)mld.pExtraData; 00319 lpExtraData && lpExtraData->cbSize; 00320 (LPBYTE)lpExtraData += dwSize 00321 ) 00322 { 00323 dwSize = lpExtraData->cbSize; 00324 if (dwSize) 00325 { 00326 if (lpExtraData->dwSignature == NT_CONSOLE_PROPS_SIG) 00327 { 00328 00329 RtlCopyMemory( &((LPLNKPROPNTCONSOLE)lpvBuffer)->console_props, 00330 lpExtraData, 00331 sizeof( NT_CONSOLE_PROPS ) 00332 ); 00333 fResult = LINK_FULLINFO; 00334 #if !defined(FE_SB) 00335 break; 00336 #endif 00337 } 00338 #if defined(FE_SB) 00339 if (lpExtraData->dwSignature == NT_FE_CONSOLE_PROPS_SIG) 00340 { 00341 LPNT_FE_CONSOLE_PROPS lpFEExtraData = (LPNT_FE_CONSOLE_PROPS)lpExtraData; 00342 00343 RtlCopyMemory( &((LPLNKPROPNTCONSOLE)lpvBuffer)->fe_console_props, 00344 lpFEExtraData, 00345 sizeof( NT_FE_CONSOLE_PROPS ) 00346 ); 00347 } 00348 #endif 00349 } 00350 } 00351 00352 #if 0 00353 #define ConsoleInfo ((LPLNKPROPNTCONSOLE)lpvBuffer) 00354 { 00355 TCHAR szTemp[ 256 ]; 00356 INT i; 00357 00358 wsprintf( szTemp, TEXT("[GetLinkProperties -- Link Properties for %s]\n"), pszLinkName ); 00359 OutputDebugString( szTemp ); 00360 wsprintf( szTemp, TEXT(" wFillAttribute = 0x%04X\n"), ConsoleInfo->console_props.wFillAttribute ); 00361 OutputDebugString( szTemp ); 00362 wsprintf( szTemp, TEXT(" wPopupFillAttribute = 0x%04X\n"), ConsoleInfo->console_props.wPopupFillAttribute ); 00363 OutputDebugString( szTemp ); 00364 wsprintf( szTemp, TEXT(" dwScreenBufferSize = (%d , %d)\n"), ConsoleInfo->console_props.dwScreenBufferSize.X, ConsoleInfo->console_props.dwScreenBufferSize.Y ); 00365 OutputDebugString( szTemp ); 00366 wsprintf( szTemp, TEXT(" dwWindowSize = (%d , %d)\n"), ConsoleInfo->console_props.dwWindowSize.X, ConsoleInfo->console_props.dwWindowSize.Y ); 00367 OutputDebugString( szTemp ); 00368 wsprintf( szTemp, TEXT(" dwWindowOrigin = (%d , %d)\n"), ConsoleInfo->console_props.dwWindowOrigin.X, ConsoleInfo->console_props.dwWindowOrigin.Y ); 00369 OutputDebugString( szTemp ); 00370 wsprintf( szTemp, TEXT(" nFont = 0x%X\n"), ConsoleInfo->console_props.nFont ); 00371 OutputDebugString( szTemp ); 00372 wsprintf( szTemp, TEXT(" nInputBufferSize = 0x%X\n"), ConsoleInfo->console_props.nInputBufferSize ); 00373 OutputDebugString( szTemp ); 00374 wsprintf( szTemp, TEXT(" dwFontSize = (%d , %d)\n"), ConsoleInfo->console_props.dwFontSize.X, ConsoleInfo->console_props.dwFontSize.Y ); 00375 OutputDebugString( szTemp ); 00376 wsprintf( szTemp, TEXT(" uFontFamily = 0x%08X\n"), ConsoleInfo->console_props.uFontFamily ); 00377 OutputDebugString( szTemp ); 00378 wsprintf( szTemp, TEXT(" uFontWeight = 0x%08X\n"), ConsoleInfo->console_props.uFontWeight ); 00379 OutputDebugString( szTemp ); 00380 wsprintf( szTemp, TEXT(" FaceName = %ws\n"), ConsoleInfo->console_props.FaceName ); 00381 OutputDebugString( szTemp ); 00382 wsprintf( szTemp, TEXT(" uCursorSize = %d\n"), ConsoleInfo->console_props.uCursorSize ); 00383 OutputDebugString( szTemp ); 00384 wsprintf( szTemp, TEXT(" bFullScreen = %s\n"), ConsoleInfo->console_props.bFullScreen ? TEXT("TRUE") : TEXT("FALSE") ); 00385 OutputDebugString( szTemp ); 00386 wsprintf( szTemp, TEXT(" bQuickEdit = %s\n"), ConsoleInfo->console_props.bQuickEdit ? TEXT("TRUE") : TEXT("FALSE") ); 00387 OutputDebugString( szTemp ); 00388 wsprintf( szTemp, TEXT(" bInsertMode = %s\n"), ConsoleInfo->console_props.bInsertMode ? TEXT("TRUE") : TEXT("FALSE") ); 00389 OutputDebugString( szTemp ); 00390 wsprintf( szTemp, TEXT(" bAutoPosition = %s\n"), ConsoleInfo->console_props.bAutoPosition ? TEXT("TRUE") : TEXT("FALSE") ); 00391 OutputDebugString( szTemp ); 00392 wsprintf( szTemp, TEXT(" uHistoryBufferSize = %d\n"), ConsoleInfo->console_props.uHistoryBufferSize ); 00393 OutputDebugString( szTemp ); 00394 wsprintf( szTemp, TEXT(" uNumHistoryBuffers = %d\n"), ConsoleInfo->console_props.uNumberOfHistoryBuffers ); 00395 OutputDebugString( szTemp ); 00396 wsprintf( szTemp, TEXT(" bHistoryNoDup = %s\n"), ConsoleInfo->console_props.bHistoryNoDup ? TEXT("TRUE") : TEXT("FALSE") ); 00397 OutputDebugString( szTemp ); 00398 OutputDebugString( TEXT(" ColorTable = [") ); 00399 i=0; 00400 while( i < 16 ) 00401 { 00402 OutputDebugString( TEXT("\n ") ); 00403 wsprintf( szTemp, TEXT("0x%08X "), ConsoleInfo->console_props.ColorTable[i++]); 00404 OutputDebugString( szTemp ); 00405 wsprintf( szTemp, TEXT("0x%08X "), ConsoleInfo->console_props.ColorTable[i++]); 00406 OutputDebugString( szTemp ); 00407 wsprintf( szTemp, TEXT("0x%08X "), ConsoleInfo->console_props.ColorTable[i++]); 00408 OutputDebugString( szTemp ); 00409 wsprintf( szTemp, TEXT("0x%08X "), ConsoleInfo->console_props.ColorTable[i++]); 00410 OutputDebugString( szTemp ); 00411 } 00412 OutputDebugString( TEXT("]\n\n") ); 00413 } 00414 #undef ConsoleInfo 00415 #endif 00416 00417 Cleanup: 00418 if (mld.pszName) 00419 ConsoleHeapFree( mld.pszName ); 00420 if (mld.pszRelPath) 00421 ConsoleHeapFree( mld.pszRelPath ); 00422 if (mld.pszWorkingDir) 00423 ConsoleHeapFree( mld.pszWorkingDir ); 00424 if (mld.pszArgs) 00425 ConsoleHeapFree( mld.pszArgs ); 00426 if (mld.pszIconLocation) 00427 ConsoleHeapFree( mld.pszIconLocation ); 00428 if (mld.pExtraData) 00429 ConsoleHeapFree( mld.pExtraData ); 00430 00431 return fResult; 00432 00433 }

Generated on Sat May 15 19:40:38 2004 for test by doxygen 1.3.7