716 lines
20 KiB
C
716 lines
20 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1998 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
lnkstub.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Implements a simple application that replaces incompatible applications
|
||
|
detected dynamically during Win9x upgrade to Windows 2000.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Calin Negreanu (calinn) 25-Feb-1999
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "pch.h"
|
||
|
#include "resource.h"
|
||
|
#include "msg.h"
|
||
|
#include <winbasep.h>
|
||
|
#include <shellapi.h>
|
||
|
|
||
|
//
|
||
|
// Globals
|
||
|
//
|
||
|
|
||
|
HINSTANCE g_hInst;
|
||
|
HANDLE g_hHeap;
|
||
|
BOOL g_RemoveLnk = FALSE;
|
||
|
BOOL g_RestoreLnk = FALSE;
|
||
|
BOOL g_RunOrgApp = FALSE;
|
||
|
HICON g_hIcon = NULL;
|
||
|
BOOL g_ReportAvailable = FALSE;
|
||
|
BOOL g_StartAppAvailable = FALSE;
|
||
|
BOOL g_RemoveLnkAvailable = FALSE;
|
||
|
BOOL g_RestoreLnkAvailable = FALSE;
|
||
|
PCTSTR g_ReportPath = NULL;
|
||
|
DWORD g_Announcement = ACT_INC_NOBADAPPS;
|
||
|
DWORD g_Availability = 1;
|
||
|
PCTSTR g_ActualLnkName = NULL;
|
||
|
|
||
|
//
|
||
|
// Library prototypes
|
||
|
//
|
||
|
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
MigUtil_Entry (
|
||
|
HINSTANCE hInstance,
|
||
|
DWORD dwReason,
|
||
|
PVOID lpReserved
|
||
|
);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Local prototypes
|
||
|
//
|
||
|
|
||
|
BOOL
|
||
|
CALLBACK
|
||
|
DialogProc (
|
||
|
HWND hdlg,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Implementation
|
||
|
//
|
||
|
|
||
|
|
||
|
VOID
|
||
|
pSetProgramIcon (
|
||
|
PCTSTR OrigIconPath,
|
||
|
INT OrigIconNr
|
||
|
)
|
||
|
{
|
||
|
HINSTANCE iconFile;
|
||
|
|
||
|
iconFile = LoadLibraryEx (OrigIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||
|
if (iconFile) {
|
||
|
g_hIcon = LoadIcon (iconFile, MAKEINTRESOURCE(OrigIconNr));
|
||
|
FreeLibrary (iconFile);
|
||
|
}
|
||
|
if (g_hIcon == NULL) {
|
||
|
g_hIcon = LoadIcon (NULL, IDI_EXCLAMATION);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
pIsFileAccessible (
|
||
|
IN PCTSTR FileName,
|
||
|
IN DWORD DesiredAccess
|
||
|
)
|
||
|
{
|
||
|
HANDLE fileHandle;
|
||
|
|
||
|
fileHandle = CreateFile (
|
||
|
FileName,
|
||
|
DesiredAccess,
|
||
|
FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
|
||
|
NULL
|
||
|
);
|
||
|
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
CloseHandle (fileHandle);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
pRestoreLnk (
|
||
|
IN PCTSTR LnkName,
|
||
|
IN PCTSTR LnkTarget,
|
||
|
IN PCTSTR LnkArgs,
|
||
|
IN PCTSTR LnkWorkDir,
|
||
|
IN PCTSTR LnkIconPath,
|
||
|
IN INT LnkIconNr,
|
||
|
IN INT ShowMode
|
||
|
)
|
||
|
{
|
||
|
IShellLink *psl = NULL;
|
||
|
IPersistFile *ppf = NULL;
|
||
|
BOOL result = FALSE;
|
||
|
|
||
|
HRESULT comResult;
|
||
|
|
||
|
comResult = CoInitialize (NULL);
|
||
|
if (FAILED (comResult)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
__try {
|
||
|
if (!DoesFileExist (LnkName)) {
|
||
|
__leave;
|
||
|
}
|
||
|
if (((LnkTarget == NULL) || (LnkTarget [0] == 0)) &&
|
||
|
((LnkWorkDir == NULL) || (LnkWorkDir [0] == 0)) &&
|
||
|
((LnkIconPath == NULL) || (LnkIconPath [0] == 0)) &&
|
||
|
(LnkIconNr == 0)
|
||
|
) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
comResult = CoCreateInstance (
|
||
|
&CLSID_ShellLink,
|
||
|
NULL,
|
||
|
CLSCTX_INPROC_SERVER,
|
||
|
&IID_IShellLink,
|
||
|
(void **) &psl);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
comResult = psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile, (void **) &ppf);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We only load if the file was really a LNK
|
||
|
//
|
||
|
comResult = ppf->lpVtbl->Load(ppf, LnkName, STGM_READ);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (LnkTarget != NULL) {
|
||
|
comResult = psl->lpVtbl->SetPath (psl, LnkTarget);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
}
|
||
|
if (LnkArgs != NULL) {
|
||
|
comResult = psl->lpVtbl->SetArguments (psl, LnkArgs);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
}
|
||
|
if (LnkWorkDir != NULL) {
|
||
|
comResult = psl->lpVtbl->SetWorkingDirectory (psl, LnkWorkDir);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
}
|
||
|
if (LnkIconPath != NULL) {
|
||
|
comResult = psl->lpVtbl->SetIconLocation (psl, LnkIconPath, LnkIconNr);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
comResult = psl->lpVtbl->SetShowCmd (psl, ShowMode);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
comResult = ppf->lpVtbl->Save (ppf, LnkName, FALSE);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
comResult = ppf->lpVtbl->SaveCompleted (ppf, LnkName);
|
||
|
if (comResult != S_OK) {
|
||
|
__leave;
|
||
|
}
|
||
|
result = TRUE;
|
||
|
}
|
||
|
__finally {
|
||
|
if (ppf != NULL) {
|
||
|
ppf->lpVtbl->Release (ppf);
|
||
|
ppf = NULL;
|
||
|
}
|
||
|
if (psl != NULL) {
|
||
|
psl->lpVtbl->Release (psl);
|
||
|
psl = NULL;
|
||
|
}
|
||
|
CoUninitialize ();
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
INT
|
||
|
WINAPI
|
||
|
WinMain (
|
||
|
HINSTANCE hInstance,
|
||
|
HINSTANCE hPrevInstance,
|
||
|
PSTR AnsiCmdLine,
|
||
|
INT CmdShow
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
The entry point to lnkstub.exe. All the work is done in a dialog box,
|
||
|
so no message loop is necessary.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
hInstance - The instance handle of this EXE
|
||
|
hPrevInstance - The previous instance handle of this EXE if it is
|
||
|
running, or NULL if no other instances exist.
|
||
|
AnsiCmdLine - The command line (ANSI version)
|
||
|
CmdShow - The ShowWindow command passed by the shell
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Returns -1 if an error occurred, or 0 if the exe completed.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
UINT Result;
|
||
|
TCHAR winDir [MAX_PATH];
|
||
|
STARTUPINFO startInfo;
|
||
|
PCTSTR OrigLnkName = NULL;
|
||
|
PCTSTR OrigTarget = NULL;
|
||
|
PCTSTR OrigArgs = NULL;
|
||
|
PCTSTR OrigWorkDir = NULL;
|
||
|
PCTSTR OrigIconPath = NULL;
|
||
|
INT OrigIconNr = 0;
|
||
|
INT OrigShowMode = SW_NORMAL;
|
||
|
PCTSTR LnkStubDatFile = NULL;
|
||
|
PBYTE LnkStubDatPtr = NULL;
|
||
|
PBYTE LnkStubDatPtrTmp = NULL;
|
||
|
HANDLE StubMapHandle = NULL;
|
||
|
HANDLE StubFileHandle = NULL;
|
||
|
INT ofsHeader;
|
||
|
PDWORD offset;
|
||
|
FILETIME fileTime;
|
||
|
FILETIME reqFileTime;
|
||
|
WIN32_FIND_DATA findData;
|
||
|
BOOL shouldRestoreLnk = FALSE;
|
||
|
PCTSTR reqFilePath = NULL;
|
||
|
PCTSTR reqFileFullPath = NULL;
|
||
|
PCTSTR oldFileSpec = NULL;
|
||
|
PTSTR oldFilePtr = NULL;
|
||
|
INITCOMMONCONTROLSEX init = {sizeof (INITCOMMONCONTROLSEX), 0};
|
||
|
|
||
|
InitCommonControlsEx (&init);
|
||
|
|
||
|
g_hInst = hInstance;
|
||
|
g_hHeap = GetProcessHeap();
|
||
|
|
||
|
MigUtil_Entry (hInstance, DLL_PROCESS_ATTACH, NULL);
|
||
|
|
||
|
if (GetWindowsDirectory (winDir, MAX_PATH)) {
|
||
|
g_ReportPath = JoinPaths (winDir, S_UPGRADEHTM);
|
||
|
g_ReportAvailable = DoesFileExist (g_ReportPath) && pIsFileAccessible (g_ReportPath, GENERIC_READ);
|
||
|
LnkStubDatFile = JoinPaths (winDir, S_LNKSTUB_DAT);
|
||
|
}
|
||
|
|
||
|
// let's see if we can get the LNK that launched us.
|
||
|
GetStartupInfo (&startInfo);
|
||
|
if (startInfo.dwFlags & STARTF_TITLEISLINKNAME) {
|
||
|
g_ActualLnkName = DuplicatePathString (startInfo.lpTitle, 0);
|
||
|
g_RemoveLnkAvailable = DoesFileExist (g_ActualLnkName) && pIsFileAccessible (g_ActualLnkName, GENERIC_READ|GENERIC_WRITE);
|
||
|
}
|
||
|
|
||
|
// now let's see if we can find data about our original LNK
|
||
|
if (LnkStubDatFile) {
|
||
|
__try {
|
||
|
|
||
|
LnkStubDatPtr = MapFileIntoMemoryEx (LnkStubDatFile, &StubMapHandle, &StubFileHandle, TRUE);
|
||
|
if (LnkStubDatPtr) {
|
||
|
ofsHeader = atoi (AnsiCmdLine) - 1;
|
||
|
if (ofsHeader >= 0) {
|
||
|
|
||
|
//
|
||
|
// Read details about original LNK. See w95upgnt\filemig.c
|
||
|
// for format of lnkstub.dat
|
||
|
//
|
||
|
|
||
|
offset = (PDWORD) (LnkStubDatPtr + ofsHeader * sizeof (DWORD));
|
||
|
|
||
|
OrigLnkName = (PCTSTR) (LnkStubDatPtr + *offset);
|
||
|
OrigTarget = GetEndOfString (OrigLnkName) + 1;
|
||
|
OrigArgs = GetEndOfString (OrigTarget) + 1;
|
||
|
OrigWorkDir = GetEndOfString (OrigArgs) + 1;
|
||
|
OrigIconPath = GetEndOfString (OrigWorkDir) + 1;
|
||
|
LnkStubDatPtrTmp = (PBYTE) (GetEndOfString (OrigIconPath) + 1);
|
||
|
|
||
|
OrigIconNr = *((PINT) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (INT);
|
||
|
|
||
|
OrigShowMode = *((PINT) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (INT);
|
||
|
|
||
|
g_Announcement = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
g_Availability = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
fileTime.dwLowDateTime = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
fileTime.dwHighDateTime = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
reqFilePath = (PTSTR)LnkStubDatPtrTmp;
|
||
|
|
||
|
//
|
||
|
// Continue reading [in a loop] the list of required
|
||
|
// files. This is how lnkstub detects changes from a
|
||
|
// reinstall or uninstall, and auto-removes itself.
|
||
|
//
|
||
|
|
||
|
shouldRestoreLnk = FALSE;
|
||
|
while (reqFilePath [0]) {
|
||
|
if (!shouldRestoreLnk) {
|
||
|
oldFileSpec = DuplicatePathString (OrigTarget, 0);
|
||
|
oldFilePtr = (PTSTR)GetFileNameFromPath (oldFileSpec);
|
||
|
if (oldFilePtr) {
|
||
|
*oldFilePtr = 0;
|
||
|
}
|
||
|
reqFileFullPath = JoinPaths (oldFileSpec, reqFilePath);
|
||
|
if (!DoesFileExistEx (reqFileFullPath, &findData)) {
|
||
|
shouldRestoreLnk = FALSE;
|
||
|
}
|
||
|
FreePathString (reqFileFullPath);
|
||
|
FreePathString (oldFileSpec);
|
||
|
}
|
||
|
|
||
|
LnkStubDatPtrTmp = (PBYTE) (GetEndOfString (reqFilePath) + 1);
|
||
|
|
||
|
reqFileTime.dwLowDateTime = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
reqFileTime.dwHighDateTime = *((PDWORD) LnkStubDatPtrTmp);
|
||
|
LnkStubDatPtrTmp += sizeof (DWORD);
|
||
|
|
||
|
reqFilePath = (PTSTR)LnkStubDatPtrTmp;
|
||
|
|
||
|
if (!shouldRestoreLnk) {
|
||
|
if ((findData.ftLastWriteTime.dwLowDateTime != reqFileTime.dwLowDateTime) ||
|
||
|
(findData.ftLastWriteTime.dwHighDateTime != reqFileTime.dwHighDateTime)
|
||
|
) {
|
||
|
shouldRestoreLnk = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save data from memory mapped lnkstub.dat into path pool
|
||
|
//
|
||
|
|
||
|
OrigLnkName = DuplicatePathString (OrigLnkName, 0);
|
||
|
OrigTarget = DuplicatePathString (OrigTarget, 0);
|
||
|
OrigArgs = DuplicatePathString (OrigArgs, 0);
|
||
|
OrigWorkDir = DuplicatePathString (OrigWorkDir, 0);
|
||
|
OrigIconPath = DuplicatePathString (OrigIconPath, 0);
|
||
|
g_StartAppAvailable = DoesFileExistEx (OrigTarget, &findData);
|
||
|
g_RestoreLnkAvailable = g_RemoveLnkAvailable && g_StartAppAvailable;
|
||
|
if (!shouldRestoreLnk) {
|
||
|
if ((findData.ftLastWriteTime.dwLowDateTime != fileTime.dwLowDateTime) ||
|
||
|
(findData.ftLastWriteTime.dwHighDateTime != fileTime.dwHighDateTime)
|
||
|
) {
|
||
|
shouldRestoreLnk = TRUE;
|
||
|
}
|
||
|
}
|
||
|
shouldRestoreLnk = shouldRestoreLnk && g_StartAppAvailable;
|
||
|
}
|
||
|
}
|
||
|
} __except (1) {
|
||
|
UnmapFile (LnkStubDatPtr, StubMapHandle, StubFileHandle);
|
||
|
LnkStubDatPtr = NULL;
|
||
|
OrigLnkName = NULL;
|
||
|
OrigTarget = NULL;
|
||
|
OrigArgs = NULL;
|
||
|
OrigWorkDir = NULL;
|
||
|
OrigIconPath = NULL;
|
||
|
g_StartAppAvailable = FALSE;
|
||
|
g_RestoreLnkAvailable = FALSE;
|
||
|
}
|
||
|
|
||
|
if (LnkStubDatPtr) {
|
||
|
UnmapFile (LnkStubDatPtr, StubMapHandle, StubFileHandle);
|
||
|
LnkStubDatPtr = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (OrigIconPath && *OrigIconPath) {
|
||
|
pSetProgramIcon (OrigIconPath, OrigIconNr);
|
||
|
} else {
|
||
|
pSetProgramIcon (OrigTarget, OrigIconNr);
|
||
|
}
|
||
|
|
||
|
if (shouldRestoreLnk) {
|
||
|
g_RestoreLnk = TRUE;
|
||
|
g_RunOrgApp = TRUE;
|
||
|
} else {
|
||
|
switch (g_Announcement) {
|
||
|
case ACT_REINSTALL:
|
||
|
case ACT_REINSTALL_BLOCK:
|
||
|
Result = DialogBox (
|
||
|
hInstance,
|
||
|
MAKEINTRESOURCE(IDD_REINST_DLG),
|
||
|
NULL,
|
||
|
DialogProc
|
||
|
);
|
||
|
break;
|
||
|
case ACT_INC_PREINSTUTIL:
|
||
|
Result = DialogBox (
|
||
|
hInstance,
|
||
|
MAKEINTRESOURCE(IDD_PREINSTUTIL_DLG),
|
||
|
NULL,
|
||
|
DialogProc
|
||
|
);
|
||
|
break;
|
||
|
case ACT_INC_SIMILAROSFUNC:
|
||
|
Result = DialogBox (
|
||
|
hInstance,
|
||
|
MAKEINTRESOURCE(IDD_SIMILAROSFUNCT_DLG),
|
||
|
NULL,
|
||
|
DialogProc
|
||
|
);
|
||
|
break;
|
||
|
case ACT_INC_IHVUTIL:
|
||
|
Result = DialogBox (
|
||
|
hInstance,
|
||
|
MAKEINTRESOURCE(IDD_IHVUTIL_DLG),
|
||
|
NULL,
|
||
|
DialogProc
|
||
|
);
|
||
|
break;
|
||
|
default:
|
||
|
Result = DialogBox (
|
||
|
hInstance,
|
||
|
MAKEINTRESOURCE(IDD_INCOMP_DLG),
|
||
|
NULL,
|
||
|
DialogProc
|
||
|
);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_RestoreLnk) {
|
||
|
MYASSERT (!g_RemoveLnk);
|
||
|
if (!pRestoreLnk (
|
||
|
g_ActualLnkName,
|
||
|
OrigTarget,
|
||
|
OrigArgs,
|
||
|
OrigWorkDir,
|
||
|
OrigIconPath,
|
||
|
OrigIconNr-1,
|
||
|
OrigShowMode
|
||
|
)) {
|
||
|
DEBUGMSG ((DBG_ERROR, "Cannot restore %s", g_ActualLnkName));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_RunOrgApp) {
|
||
|
MYASSERT (!g_RemoveLnk);
|
||
|
if (ShellExecute (NULL, NULL, OrigTarget, OrigArgs, OrigWorkDir, SW_SHOWDEFAULT) <= (HINSTANCE)32) {
|
||
|
DEBUGMSG ((DBG_ERROR, "Cannot start %s", OrigTarget));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_RemoveLnk) {
|
||
|
if (!DeleteFile (g_ActualLnkName)) {
|
||
|
DEBUGMSG ((DBG_ERROR, "Cannot remove %s", g_ActualLnkName));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (OrigIconPath) {
|
||
|
FreePathString (OrigIconPath);
|
||
|
}
|
||
|
|
||
|
if (OrigWorkDir) {
|
||
|
FreePathString (OrigWorkDir);
|
||
|
}
|
||
|
|
||
|
if (OrigArgs) {
|
||
|
FreePathString (OrigArgs);
|
||
|
}
|
||
|
|
||
|
if (OrigTarget) {
|
||
|
FreePathString (OrigTarget);
|
||
|
}
|
||
|
|
||
|
if (OrigLnkName) {
|
||
|
FreePathString (OrigLnkName);
|
||
|
}
|
||
|
|
||
|
if (g_ActualLnkName) {
|
||
|
FreePathString (g_ActualLnkName);
|
||
|
g_ActualLnkName = NULL;
|
||
|
}
|
||
|
|
||
|
if (LnkStubDatFile) {
|
||
|
FreePathString (LnkStubDatFile);
|
||
|
}
|
||
|
|
||
|
if (g_ReportPath) {
|
||
|
FreePathString (g_ReportPath);
|
||
|
}
|
||
|
|
||
|
MigUtil_Entry (hInstance, DLL_PROCESS_DETACH, NULL);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CALLBACK
|
||
|
DialogProc (
|
||
|
HWND hdlg,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
DialogProc is the dialog procedure for the main dialog.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
hdlg - Dialog window handle
|
||
|
uMsg - Message to process
|
||
|
wParam - Message-specific
|
||
|
lParam - Message-specific
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if the message was processed, or FALSE if the message should be
|
||
|
processed by the OS.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
static RECT LargeWndRect;
|
||
|
static RECT SmallWndRect;
|
||
|
static TCHAR LargeCaption[128];
|
||
|
static TCHAR SmallCaption[128];
|
||
|
static BOOL LargeWnd;
|
||
|
RECT ButtonRect;
|
||
|
PTSTR lnkName = NULL;
|
||
|
PTSTR extPtr = NULL;
|
||
|
BOOL showReport = TRUE;
|
||
|
|
||
|
HINSTANCE result;
|
||
|
|
||
|
switch (uMsg) {
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
if (g_ActualLnkName) {
|
||
|
lnkName = DuplicatePathString (GetFileNameFromPath (g_ActualLnkName), 0);
|
||
|
if (lnkName) {
|
||
|
extPtr = (PTSTR)GetFileExtensionFromPath (lnkName);
|
||
|
if (extPtr) {
|
||
|
extPtr = _tcsdec (lnkName, extPtr);
|
||
|
if (extPtr) {
|
||
|
*extPtr = 0;
|
||
|
SetWindowText (hdlg, lnkName);
|
||
|
}
|
||
|
}
|
||
|
FreePathString (lnkName);
|
||
|
}
|
||
|
}
|
||
|
showReport = g_Availability && g_ReportAvailable;
|
||
|
GetWindowText (GetDlgItem (hdlg, IDC_OPTIONS), LargeCaption, 125);
|
||
|
GetWindowText (GetDlgItem (hdlg, IDC_OPTIONS), SmallCaption, 125);
|
||
|
_tcscat (LargeCaption, TEXT(" <<"));
|
||
|
_tcscat (SmallCaption, TEXT(" >>"));
|
||
|
SetDlgItemText (hdlg, IDC_OPTIONS, SmallCaption);
|
||
|
|
||
|
GetWindowRect (hdlg, &LargeWndRect);
|
||
|
GetWindowRect (GetDlgItem (hdlg, IDC_DLG_SIZE_SEPARATOR), &ButtonRect);
|
||
|
CopyMemory (&SmallWndRect, &LargeWndRect, sizeof (RECT));
|
||
|
SmallWndRect.bottom = ButtonRect.bottom;
|
||
|
|
||
|
SetWindowPos (
|
||
|
hdlg,
|
||
|
NULL,
|
||
|
0,
|
||
|
0,
|
||
|
SmallWndRect.right-SmallWndRect.left,
|
||
|
SmallWndRect.bottom-SmallWndRect.top,
|
||
|
SWP_NOMOVE|SWP_NOZORDER
|
||
|
);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_START), FALSE);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_REMOVE), FALSE);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_RESTORE), FALSE);
|
||
|
LargeWnd = FALSE;
|
||
|
if (!showReport) {
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_REPORTBUTTON), FALSE);
|
||
|
ShowWindow (GetDlgItem (hdlg, IDC_REPORTTEXT), SW_HIDE);
|
||
|
} else {
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_REPORTBUTTON), TRUE);
|
||
|
ShowWindow (GetDlgItem (hdlg, IDC_REPORTTEXT), SW_SHOW);
|
||
|
}
|
||
|
SendDlgItemMessage (hdlg, IDC_PROGICON, STM_SETICON, (LPARAM)g_hIcon, 0);
|
||
|
return FALSE;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam)) {
|
||
|
case IDCANCEL:
|
||
|
EndDialog (hdlg, LOWORD (wParam));
|
||
|
break;
|
||
|
case IDC_REPORTBUTTON:
|
||
|
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
result = ShellExecute (
|
||
|
hdlg,
|
||
|
NULL,
|
||
|
g_ReportPath,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
SW_SHOW
|
||
|
);
|
||
|
}
|
||
|
break;
|
||
|
case IDC_OPTIONS:
|
||
|
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
LargeWnd = !LargeWnd;
|
||
|
SetWindowPos (
|
||
|
hdlg,
|
||
|
NULL,
|
||
|
0,
|
||
|
0,
|
||
|
LargeWnd?LargeWndRect.right-LargeWndRect.left:SmallWndRect.right-SmallWndRect.left,
|
||
|
LargeWnd?LargeWndRect.bottom-LargeWndRect.top:SmallWndRect.bottom-SmallWndRect.top,
|
||
|
SWP_NOMOVE|SWP_NOZORDER
|
||
|
);
|
||
|
SetDlgItemText (hdlg, IDC_OPTIONS, LargeWnd?LargeCaption:SmallCaption);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_START), LargeWnd & g_StartAppAvailable);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_REMOVE), LargeWnd & g_RemoveLnkAvailable);
|
||
|
EnableWindow (GetDlgItem (hdlg, IDC_RESTORE), LargeWnd & g_RestoreLnkAvailable);
|
||
|
}
|
||
|
break;
|
||
|
case IDC_START:
|
||
|
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
g_RunOrgApp = TRUE;
|
||
|
EndDialog (hdlg, LOWORD (wParam));
|
||
|
}
|
||
|
break;
|
||
|
case IDC_REMOVE:
|
||
|
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
g_RemoveLnk = TRUE;
|
||
|
EndDialog (hdlg, LOWORD (wParam));
|
||
|
}
|
||
|
break;
|
||
|
case IDC_RESTORE:
|
||
|
if (HIWORD (wParam) == BN_CLICKED) {
|
||
|
g_RestoreLnk = TRUE;
|
||
|
EndDialog (hdlg, LOWORD (wParam));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|