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.
 
 
 
 
 
 

228 lines
4.2 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
asynchlp.c
Abstract:
This is the client windows suuport layer for async I/O requests.
Author:
Steven Zeck (stevez) 03/25/92
--*/
#include "windows.h"
#include "asynchlp.h"
// Some inline assembler for trival windows functions.
#define WinEnterCritical() _asm cli
#define WinExitCritical() _asm sti
#define int3() _asm int 3
extern HANDLE hInstanceDLL; // handle of DLL
PASYNC_REQUEST pRoot; // head of linked list of requests
PASYNC_REQUEST CurrentRequest; // current request, before yield
void _pascal _export _far
AsyncDone(
IN void _far * Context
)
/*++
Routine Description:
Mark an async request completed. This is called at interrupt time.
Arguments:
Context - Context of request that has been completed.
--*/
{
PASYNC_REQUEST _far * pAsyncLast, pAsyncCur;
// int3();
// Search the list of pending operations for the one done.
for (pAsyncLast = &pRoot, pAsyncCur = pRoot; pAsyncCur;
pAsyncLast = &pAsyncCur->pNext, pAsyncCur = pAsyncCur->pNext)
if (pAsyncCur->Context == Context)
{
pAsyncCur->fDone = TRUE;
// If the dialog has initialized itself, send a message to
// it to quit, which will return control to AsyncReadWrite().
if (pAsyncCur->hWnd)
PostMessage(pAsyncCur->hWnd, WM_USER, END_DIALOG, 0);
// remove the completed async block from the list
*pAsyncLast = pAsyncCur->pNext;
return;
}
}
unsigned int _far _pascal _export
BusyBox(
IN HWND hDialog,
IN unsigned Message,
IN unsigned int wParam,
IN LONG lParam
)
/*++
Routine Description:
This function is the dialog procedure for the dialog which allows
the user to switch away from the application.
Arguments:
hDialog - handle of dialog block.
Message - windows message value.
wParam - parameter work, contains our private message token to quit.
lParam - unused.
Returns:
FALSE
--*/
{
switch (Message){
case WM_INITDIALOG:
// Fill in my window handle so I can receive the finished message.
WinEnterCritical();
if (!CurrentRequest->fDone)
CurrentRequest->hWnd = hDialog;
WinExitCritical();
if (CurrentRequest->fDone)
EndDialog(hDialog, 0);
break;
// I recieved the Quit message from the asyncDone function, so
// remove the dialog and return to AsyncSendReceive.
case WM_USER:
if (wParam == END_DIALOG)
EndDialog(hDialog, 0);
}
return(FALSE);
}
unsigned short _pascal _far
AsyncInitialize (
OUT PASYNC_REQUEST AsyncBlock,
IN void _far * Context
)
/*++
Routine Description:
Get an Async request ready to be initialed.
Arguments:
AsyncBlock - the async block that we are about to initialize.
Context - context value that is call with Async Done by the
transport at interrupt time.
Returns:
TRUE if initialization was OK, else FALSE for dead lock detected.
--*/
{
PASYNC_REQUEST AsyncItem;
HANDLE TaskSelf = GetCurrentTask();
// Scan the list of pending request to detect deadlock.
for ( AsyncItem = pRoot; AsyncItem; AsyncItem = AsyncItem->pNext)
if (AsyncItem->Owner == TaskSelf)
return(FALSE);
// int3();
// Link the request into list of active requests.
WinEnterCritical();
AsyncBlock->Owner = TaskSelf;
AsyncBlock->hWnd = 0;
AsyncBlock->fDone = FALSE;
AsyncBlock->TimeRequested = GetCurrentTime();
AsyncBlock->Context = Context;
CurrentRequest = AsyncBlock;
AsyncBlock->pNext = pRoot;
pRoot = AsyncBlock;
WinExitCritical();
return(TRUE);
}
void _pascal _far
AsyncWait (
OUT PASYNC_REQUEST AsyncBlock
)
/*++
Routine Description:
Wait for an Async request to finish.
Arguments:
AsyncBlock - the async block that we want to wait for.
--*/
{
// The async request is now pending. If the operation doesn't
// complete soon, then put up a dialog box which tells the user
// that an RPC request is pending which will allow them to
// switch away.
while(! AsyncBlock->fDone)
{
// Yield();
if (GetCurrentTime() > AsyncBlock->TimeRequested + AsyncDelay)
DialogBox (hInstanceDLL, "BUSYBOX", GetFocus(), BusyBox);
}
}