Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

364 lines
10 KiB

/******************************* MODULE HEADER *******************************
* utils.c
* Functions to interface to the help system.
*
*
* Copyright (C) 1993 Microsoft Corporation.
*
*****************************************************************************/
#include "rasuipch.h"
/*
* Some stuff associated with help.
*/
static WCHAR wcHelpFNM[] = L"\\hprasdui.hlp";
WCHAR *pwszHelpFile = NULL; /* Filled in when needed */
static int cHelpInit = 0; /* Only do it once */
static HHOOK hhookGetMsg;
/*
* Local function prototypes.
*/
LRESULT CALLBACK GetMsgProc( int, WPARAM, LPARAM );
/************************* Function Header *********************************
*
* Routine Description:
*
* Duplicate a Unicode string
*
* Arguments:
*
* unicodeString - Pointer to the input Unicode string
* hheap - Handle to a heap from which to allocate memory
*
* Return Value:
*
* Pointer to the resulting Unicode string
* NULL if there is an error
****************************************************************************/
PWSTR
GetStringFromUnicode(
PWSTR unicodeString,
HANDLE hHeap
)
{
PWSTR pwstr;
INT length;
ASSERTRASDD((unicodeString != NULL), "NULL Source in GetStringFromUnicode");
length = wcslen(unicodeString) + 1;
if ((pwstr = HeapAlloc(hHeap, 0, length * sizeof(WCHAR))) != NULL) {
wcscpy(pwstr, unicodeString);
} else {
RASDERRMSG("HEAPALLOC");
}
return pwstr;
}
/************************* Function Header *********************************
* vHelpInit
* Called to initialise the help operations. Not much to do, but er
* do keep track of how many times we are called, and only do the
* initialisation once, and hence make sure we free it only once.
*
* RETURNS:
* Nothing, failure of help is benign.
*
* HISTORY:
* 13:45 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
* Starting.
*
****************************************************************************/
void
vHelpInit(
HANDLE hPrinter,
BOOL bInitHelpFileOnly
)
{
DWORD dwSize; /* See how much storage is needed for file name */
DWORD cb;
PDRIVER_INFO_3 pDriverInfo = NULL;
PWSTR pDriverDirectory; /* Comes from the spooler */
if( pwszHelpFile == NULL )
{
// Attempt to get help file name using the new DRIVER_INFO_3
if (! GetPrinterDriver(hPrinter, NULL, 3, NULL, 0, &cb) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
(pDriverInfo = HeapAlloc( hGlobalHeap, 0, cb)) &&
GetPrinterDriver(hPrinter, NULL, 3, (PBYTE) pDriverInfo, cb, &cb) &&
pDriverInfo->pHelpFile != NULL)
{
pwszHelpFile = GetStringFromUnicode(pDriverInfo->pHelpFile, hGlobalHeap);
}
if (pDriverInfo != NULL) {
HeapFree( hGlobalHeap, 0, pDriverInfo );
}
// If DRIVER_INFO_3 isn't supported, get help file name
// using the same old method as before
if (pwszHelpFile == NULL)
{
pDriverDirectory = GetDriverDirectory( hGlobalHeap, hPrinter );
if( pDriverDirectory )
{
/* Grab some memory & fill it in */
dwSize = (1 + wcslen( wcHelpFNM ) + wcslen( pDriverDirectory ) )
* sizeof( WCHAR );
if( pwszHelpFile = (WCHAR *)HeapAlloc( hGlobalHeap, 0, dwSize ) )
{
wcscpy( pwszHelpFile, pDriverDirectory );
wcscat( pwszHelpFile, wcHelpFNM ); /* The name */
}
else
{
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
}
}
else
{
return ; /* Whatever it is, this should not happen */
}
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
}
}
/*
* All we need to do (and only the first time!) is put a hook function
* onto the message queue so that we can intercept the <F1> key and
* transform it into a mouse click on the "Help" button. Then the
* normal windowing code will display the help contents.This should be
* done only for old type of help, like softfont in PrinterProperties.
*/
if( cHelpInit == 0 && !bInitHelpFileOnly )
{
/* First time only */
hhookGetMsg = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, hModule,
GetCurrentThreadId() );
}
++cHelpInit; /* Only do it once */
return ;
}
/************************** Function Header *******************************
* vHelpDone
* Called to discombobulate help.
*
* RETURNS:
* Nothing.
*
* HISTORY:
* 13:09 on Mon 01 Mar 1993 -by- Lindsay Harris [lindsayh]
* Free help file name when done.
*
* 13:52 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
* First version.
*
**************************************************************************/
void
vHelpDone(
HWND hWnd, /* Required to allow us to clean up nicely */
BOOL bInitHelpFileOnly
)
{
--cHelpInit;
if( cHelpInit == 0 )
{
if (!bInitHelpFileOnly)
{
/* Does the right thing for help to go away, if shown */
vShowHelp( hWnd, HELP_QUIT, 0L, NULL );
UnhookWindowsHookEx( hhookGetMsg );
}
if( pwszHelpFile )
{
HeapFree( hGlobalHeap, 0, (LPSTR)pwszHelpFile );
pwszHelpFile = NULL;
}
}
else if( cHelpInit < 0 )
cHelpInit = 0; /* Should never happen, but.... */
return;
}
/************************** Function Header *******************************
* vShowHelp
* Front end to the help facility, basically providing a pop-up if
* the help file is not available.
*
* RETURNS:
* Nothing
*
* HISTORY:
* 13:09 on Mon 01 Mar 1993 -by- Lindsay Harris [lindsayh]
* Generate the help file name when needed.
*
* 16:29 on Mon 22 Feb 1993 -by- Lindsay Harris [lindsayh]
* First rasddui incarnation, borrowed from printman (AndrewBe).
*
**************************************************************************/
void
vShowHelp( hWnd, iType, dwData, hPrinter)
HWND hWnd; /* Window of interest */
UINT iType; /* Type of help, param #3 to WinHelp */
DWORD dwData; /* Additional data for WinHelp, sometimes optional */
HANDLE hPrinter;
{
/*
* Quite easy - simply call the WinHelp function with the parameters
* supplied to us. If this fails, then put up a stock dialog box.
* BUT the first time we figure out what the file name is. We know
* the actual name, but we don't know where it is located, so we
* need to call the spooler for that information.
*/
DWORD dwSize; /* See how much storage is needed for file name */
PWSTR pDriverDirectory; /* Comes from the spooler */
if( pwszHelpFile == NULL )
{
if( iType == HELP_QUIT )
return; /* We are going away anyway! */
pDriverDirectory = GetDriverDirectory( hGlobalHeap, hPrinter );
if( pDriverDirectory )
{
/* Grab some memory & fill it in */
dwSize = (1 + wcslen( wcHelpFNM ) + wcslen( pDriverDirectory ) )
* sizeof( WCHAR );
if( pwszHelpFile = (WCHAR *)HeapAlloc( hGlobalHeap, 0, dwSize ) )
{
wcscpy( pwszHelpFile, pDriverDirectory );
wcscat( pwszHelpFile, wcHelpFNM ); /* The name */
}
else
return;
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
}
else
{
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
return; /* Whatever it is, this should not happen */
}
}
if( !WinHelp( hWnd, pwszHelpFile, iType, dwData ) )
{
/* Well, help failed, so at least tell the user! */
DialogBox( hModule, MAKEINTRESOURCE( ERR_NO_HELP ), hWnd,
(DLGPROC)GenDlgProc );
}
return;
}
/***************************** Function Header ****************************
* GetMsgProc
* Function to hook F1 key presses and turn them into standard
* help type messages.
*
* RETURNS:
* 0 for an F1 key press, else whatever comes back from CallNextHookEx()
*
* HISTORY:
* 13:26 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
* First incarnation here, following a life in printman.c (AndrewBe)
*
**************************************************************************/
LRESULT CALLBACK
GetMsgProc( iCode, wParam, lParam )
int iCode;
WPARAM wParam;
LPARAM lParam;
{
/*
* This is the callback routine which hooks F1 keypresses.
*
* Any such message will be repackaged as a WM_COMMAND/IDD_HELP message
* and sent to the top window, which may be the frame window
* or a dialog box.
*
* See the Win32 API programming reference for a description of how this
* routine works.
*
*/
PMSG pMsg = (PMSG)lParam;
if( iCode < 0 )
return CallNextHookEx( hhookGetMsg, iCode, wParam, lParam );
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1 )
{
/* Go looking for the real parent - why? */
HWND hwndParent;
BOOL bRet;
hwndParent = pMsg->hwnd;
while( GetWindowLong( hwndParent, GWL_STYLE ) & WS_CHILD )
hwndParent = (HWND)GetWindowLong( hwndParent, GWL_HWNDPARENT );
/* Our window procs all use the same format for help operations. */
bRet = PostMessage( hwndParent, WM_COMMAND, IDD_HELP, 0L );
}
return 0;
}