windows-nt/Source/XPSP1/NT/shell/osshell/runonce/romain.c
2020-09-26 16:20:57 +08:00

327 lines
9.2 KiB
C

// **************************************************************************
//
// ROMain.C
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1992-1993
// All rights reserved
//
// The window/messages pump for RunOnce
//
// 5 June 1994 FelixA Started
//
// 23 June 94 FelixA Moved to Shell tree. Changed UI.
//
// *************************************************************************/
#include "precomp.h"
#include "regstr.h"
#include <shlwapi.h>
#include <shlwapip.h>
#include <commctrl.h>
#include <comctrlp.h>
#include <shellapi.h>
#include <winuserp.h>
#include <shlobj.h>
#include <shlobjp.h>
#include "resource.h"
#include <runonce.c> // shared runonce code
// needed to make this code compile (legacy runonce.c baggage from explorer\initcab.cpp)
BOOL g_fCleanBoot = FALSE;
BOOL g_fEndSession = FALSE;
HINSTANCE g_hInst; // current instance
BOOL InitROInstance( HINSTANCE hInstance, int nCmdShow);
typedef void (WINAPI *RUNONCEEXPROCESS)(HWND, HINSTANCE, LPSTR, int);
int ParseCmdLine(LPCTSTR lpCmdLine)
{
int Res=0;
while(*lpCmdLine)
{
while( *lpCmdLine && *lpCmdLine!=TEXT('-') && *lpCmdLine!=TEXT('/'))
lpCmdLine++;
if (!(*lpCmdLine)) {
return Res;
}
// skip over the '/'
lpCmdLine++;
if (lstrcmpi(lpCmdLine, TEXT("RunOnce6432")) == 0)
{
if (IsOS(OS_WOW6432))
{
// this means we have to process the 32-bit runonce keys for wow64
Res = Cabinet_EnumRegApps(HKEY_LOCAL_MACHINE,
REGSTR_PATH_RUNONCE,
RRA_DELETE | RRA_WAIT,
ExecuteRegAppEnumProc,
0);
}
return Res;
}
else if (lstrcmpi(lpCmdLine, TEXT("RunOnceEx6432")) == 0)
{
if (IsOS(OS_WOW6432))
{
// this means that we have to process the 32-bit runonceex keys for wow64
HINSTANCE hLib;
hLib = LoadLibrary(TEXT("iernonce.dll"));
if (hLib)
{
// Note: if ew ant TS install mode for wow64 apps we need to enable/disable install mode here
RUNONCEEXPROCESS pfnRunOnceExProcess = (RUNONCEEXPROCESS)GetProcAddress(hLib, "RunOnceExProcess");
if (pfnRunOnceExProcess)
{
// the four param in the function is due to the function cab be called
// from RunDLL which will path in those params. But RunOnceExProcess ignore all
// of them. Therefore, I don't pass any meaningful thing here.
//
pfnRunOnceExProcess(NULL, NULL, NULL, 0);
Res = 1;
}
FreeLibrary(hLib);
}
}
return Res;
}
else if (lstrcmpi(lpCmdLine, TEXT("Run6432")) == 0)
{
if (IsOS(OS_WOW6432))
{
// this means that we have to process the 32-bit Run keys for wow64
Res = Cabinet_EnumRegApps(HKEY_LOCAL_MACHINE,
REGSTR_PATH_RUN,
RRA_NOUI,
ExecuteRegAppEnumProc,
0);
}
return Res;
}
switch(*lpCmdLine)
{
case TEXT('r'):
Res|=CMD_DO_CHRIS;
break;
case TEXT('b'):
Res|=CMD_DO_REBOOT;
break;
case TEXT('s'):
Res|=CMD_DO_RESTART;
break;
}
lpCmdLine++;
}
return Res;
}
/****************************************************************************
FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
PURPOSE: calls initialization function, processes message loop
****************************************************************************/
int g_iState=0;
int __stdcall WinMainT(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
if (!hPrevInstance)
{ // Other instances of app running?
if (!InitApplication(hInstance))
{ // Initialize shared things
return (FALSE); // Exits if unable to initialize
}
}
// see if we have a commnand line switch - in a VERY bad way.
g_iState = ParseCmdLine(GetCommandLine());
if(g_iState & CMD_DO_CHRIS )
{
// Go do chris's runonce stuff.
if (!InitROInstance(hInstance, nCmdShow))
return (FALSE);
return TRUE;
}
else
{
/* Perform initializations that apply to a specific instance */
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
}
return (FALSE);
}
/****************************************************************************
FUNCTION: InitApplication(HINSTANCE)
****************************************************************************/
BOOL InitApplication(HINSTANCE hInstance)
{
// CreateGlobals();
return TRUE;
}
/****************************************************************************
FUNCTION: InitInstance(HINSTANCE, int)
****************************************************************************/
BOOL InitInstance( HINSTANCE hInstance, int nCmdShow)
{
HWND hShell=GetShellWindow();
g_hInst = hInstance; // Store instance handle in our global variable
DialogBox(hInstance, MAKEINTRESOURCE(IDD_RUNONCE),NULL,dlgProcRunOnce);
return (TRUE); // We succeeded...
}
BOOL InitROInstance( HINSTANCE hInstance, int nCmdShow)
{
g_hInst = hInstance; // Store instance handle in our global variable
// Ideally this should be sufficient.
Cabinet_EnumRegApps(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUNONCE, RRA_DELETE| RRA_WAIT, ExecuteRegAppEnumProc, 0);
return TRUE;
}
BOOL TopLeftWindow( HWND hwndChild, HWND hwndParent)
{
return SetWindowPos(hwndChild, NULL, 32, 32, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
/****************************************************************************
FUNCTION: CenterWindow (HWND, HWND)
PURPOSE: Center one window over another
COMMENTS:
Dialog boxes take on the screen position that they were designed at,
which is not always appropriate. Centering the dialog over a particular
window usually results in a better position.
****************************************************************************/
BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
{
RECT rChild, rParent;
int wChild, hChild, wParent, hParent;
int wScreen, hScreen, xNew, yNew;
HDC hdc;
// Get the Height and Width of the child window
GetWindowRect (hwndChild, &rChild);
wChild = rChild.right - rChild.left;
hChild = rChild.bottom - rChild.top;
// Get the display limits
hdc = GetDC (hwndChild);
wScreen = GetDeviceCaps (hdc, HORZRES);
hScreen = GetDeviceCaps (hdc, VERTRES);
ReleaseDC (hwndChild, hdc);
// Get the Height and Width of the parent window
if( !GetWindowRect (hwndParent, &rParent) )
{
rParent.right = wScreen;
rParent.left = 0;
rParent.top = 0;
rParent.bottom = hScreen;
}
wParent = rParent.right - rParent.left;
hParent = rParent.bottom - rParent.top;
// Calculate new X position, then adjust for screen
xNew = rParent.left + ((wParent - wChild) /2);
if (xNew < 0)
{
xNew = 0;
}
else
if ((xNew+wChild) > wScreen)
{
xNew = wScreen - wChild;
}
// Calculate new Y position, then adjust for screen
yNew = rParent.top + ((hParent - hChild) /2);
if (yNew < 0)
{
yNew = 0;
} else if ((yNew+hChild) > hScreen)
{
yNew = hScreen - hChild;
}
// Set it, and return
return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
// stolen from the CRT, used to shirink our code
int _stdcall ModuleEntry(void)
{
int i;
STARTUPINFO si;
LPTSTR pszCmdLine = GetCommandLine();
if ( *pszCmdLine == TEXT('\"') ) {
/*
* Scan, and skip over, subsequent characters until
* another double-quote or a null is encountered.
*/
while ( *++pszCmdLine && (*pszCmdLine
!= TEXT('\"')) );
/*
* If we stopped on a double-quote (usual case), skip
* over it.
*/
if ( *pszCmdLine == TEXT('\"') )
pszCmdLine++;
}
else {
while (*pszCmdLine > TEXT(' '))
pszCmdLine++;
}
/*
* Skip past any white space preceeding the second token.
*/
while (*pszCmdLine && (*pszCmdLine <= TEXT(' '))) {
pszCmdLine++;
}
si.dwFlags = 0;
GetStartupInfo(&si);
i = WinMainT(GetModuleHandle(NULL), NULL, pszCmdLine,
si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
ExitProcess(i);
return i; // We never comes here.
}