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.
 
 
 
 
 
 

298 lines
7.1 KiB

#include <pch.cxx>
#pragma hdrstop
#include <ole2.h>
#include <windows.h>
#include <shlobj.h>
#include <shlguid.h>
#define TRKDATA_ALLOCATE
#include "trkwks.hxx"
DWORD g_Debug = 0;
void Usage()
{
wprintf( L"\n"
L"Purpose: Create/resolve shell links\n"
L"Usage: tshlink <-c <link client> <link source>> | <-r <link client>>\n"
L"E.g.: tshlink -c myfile.txt.lnk myfile.txt\n"
L" tshlink -r myfile.txt.lnk\n" );
exit(0);
}
class CMyApp
{
public:
CMyApp()
{
m_hwnd = NULL;
*m_szAppName = '\0';
m_nCmdShow = 0;
}
~CMyApp() {}
public:
__declspec(dllexport)
static long FAR PASCAL
WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam);
BOOL Init( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow,
int cArg, TCHAR *rgtszArg[] );
WORD Run( void );
private:
static HWND m_hwnd;
static CHAR m_szAppName[80];
static HINSTANCE m_hInstance;
static int m_nCmdShow;
static int m_cArg;
static TCHAR ** m_rgtszArg;
};
HWND CMyApp::m_hwnd;
CHAR CMyApp::m_szAppName[80];
HINSTANCE CMyApp::m_hInstance;
int CMyApp::m_nCmdShow;
int CMyApp::m_cArg;
TCHAR ** CMyApp::m_rgtszArg;
CMyApp cMyApp;
EXTERN_C void __cdecl _tmain( int cArg, TCHAR *rgtszArg[] )
{
if( cMyApp.Init(NULL, NULL, //hInstance, hPrevInstance,
NULL, SW_SHOWNORMAL, //lpszCmdLine, nCmdShow) )
cArg, rgtszArg ))
{
cMyApp.Run();
}
}
void ShellLink( HWND hwnd, int cArg, TCHAR *rgtszArg[] );
long FAR PASCAL
CMyApp::WndProc (HWND hwnd, UINT message,
UINT wParam, LONG lParam)
{
switch (message)
{
case WM_CREATE:
ShellLink( hwnd, m_cArg, m_rgtszArg );
PostQuitMessage(0);
break;
case WM_CLOSE :
DestroyWindow( hwnd );
break;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
BOOL
CMyApp::Init( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow,
int cArg, TCHAR *rgtszArg[] )
{
WNDCLASSA wndclass;
sprintf( m_szAppName, "ShellLink" );
m_hInstance = (HINSTANCE) hInstance;
m_nCmdShow = nCmdShow;
m_cArg = cArg;
m_rgtszArg = rgtszArg;
if( !hPrevInstance )
{
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = CMyApp::WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = m_hInstance;
wndclass.hIcon = LoadIconA( m_hInstance, m_szAppName );
wndclass.hCursor = LoadCursorA( NULL, MAKEINTRESOURCEA(32512) ); // IDC_ARROW
wndclass.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = m_szAppName;
RegisterClassA( &wndclass );
}
return( TRUE ); // Successful
}
#ifdef CreateWindowA
#undef CreateWindow
#endif
WORD
CMyApp::Run( void )
{
MSG msg;
HRESULT hr;
CHAR szErrorMessage[80];
msg.wParam = 0;
m_hwnd = CreateWindowA( m_szAppName,
"ShellLink",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, m_hInstance, NULL );
if( NULL == m_hwnd )
{
sprintf( szErrorMessage, "Failed CreateWindowA (%lu)", GetLastError() );
goto Exit;
}
ShowWindow( m_hwnd, SW_MINIMIZE );
UpdateWindow( m_hwnd );
while( GetMessage( &msg, NULL, 0, 0 ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Exit:
return( msg.wParam );
}
void ShellLink( HWND hwnd, int cArg, TCHAR *rgtszArg[] )
{
HRESULT hr;
IPersistFile *ppf = NULL;
IShellLink *psl = NULL;
TCHAR tszPath[ MAX_PATH + 1 ];
TCHAR tszDir[ MAX_PATH + 1 ];
WIN32_FIND_DATA fd;
DWORD dwFlags;
try
{
if( 2 > cArg ) Usage();
if( L'-' != rgtszArg[1][0] ) Usage();
hr = CoInitialize( NULL );
if( FAILED(hr) ) throw L"Failed CoInit";
hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &psl );
if( FAILED(hr) ) throw L"Failed CoCreateInstance";
hr = psl->QueryInterface( IID_IPersistFile, (void**) &ppf );
if( FAILED(hr) ) throw L"Failed QI for IPersistFile";
switch( rgtszArg[1][1] )
{
case L'c':
case L'C':
if( 4 > cArg ) Usage();
if( L':' == rgtszArg[3][1]
||
!wcsncmp( L"\\\\", rgtszArg[3], 2 ))
{
if( L':' == rgtszArg[3][1] && L'\\' != rgtszArg[3][2] )
Usage();
wcscpy( tszPath, rgtszArg[3] );
wcscpy( tszDir, tszPath );
TCHAR *ptsz = wcsrchr( tszDir, L'\\' );
*ptsz = L'\0';
}
else
{
if( !GetCurrentDirectory( sizeof(tszDir), tszDir ))
{
hr = HRESULT_FROM_WIN32(GetLastError());
throw L"Failed GetCurrentDirectory";
}
wcscpy( tszPath, tszDir );
wcscat( tszPath, L"\\" );
wcscat( tszPath, rgtszArg[3] );
}
hr = psl->SetPath( tszPath );
if( FAILED(hr) ) throw L"Failed IShellLink::SetPath";
hr = psl->SetWorkingDirectory( tszDir );
if( FAILED(hr) ) throw L"Failed IShellLink::SetWorkingDirectory";
hr = ppf->Save( rgtszArg[2], TRUE );
if( FAILED(hr) ) throw L"Failed IPersistFile::Save";
wprintf( L"Success\n" );
break;
case L'r':
case L'R':
if( 3 > cArg ) Usage();
hr = ppf->Load( rgtszArg[2], STGM_READ );
if( FAILED(hr) ) throw L"Failed IPersistFile::Load";
dwFlags = (180*1000 << 16) | SLR_ANY_MATCH;
hr = psl->Resolve( hwnd, dwFlags );
if( FAILED(hr) ) throw L"Failed Resolve";
hr = psl->GetPath( tszPath, sizeof(tszPath), &fd, 0 );
if( FAILED(hr) ) throw L"Failed IShellLink::GetPath";
wprintf( L"Path = \"%s\"\n", tszPath );
break;
default:
Usage();
break;
} // switch
}
catch( TCHAR *tszError )
{
wprintf( L"Error: %s (%08x)\n", tszError, hr );
}
if( ppf ) ppf->Release();
if( psl ) psl->Release();
}