Callback (or posting) may also be used to receive notification that a SCSI request has completed. When callback is used, ASPI for Win32 posts completion by passing control to your callback function. For example, the following code segment sends a SCSI Inquiry command to target #2 during the WM_CREATE message.
LRESULT CALLBACK WndProc (HWND, UINT, UPARAM, LPARAM);
void APIENTRY ASPIPostProc (PSRB_ExecSCSICmd );
HWND PostHWND;
HANDLE hInstance;
.
.
.
//****************************************************************************
//
// Function: ASPIPostProc
//
// Description: If POSTING is enabled, this function is called by ASPI
// for Windows when the SCSI request has completed. This
// sample function simply posts a message to our Window
// handle to indicate that the SCSI request has completed.
//
// DoneSRB This parameter points to the ASPI SCSI Request Block (SRB)
// which has completed.
//
// Returns Nothing
//
//****************************************************************************
#ifdef WIN32
void ASPIPostProc(PSRB_ExecSCSICmd DoneSRB)
{
PostMessage(PostHWND,WM_ASPIPOST,0,(LPARAM)DoneSRB);
return;
}
#else
void _loadds __far __pascal ASPIPostProc(LPSRB DoneSRB)
{
PostMessage(PostHWND,WM_ASPIPOST,
(WORD)((SRB_ExecSCSICmd6 far *)DoneSRB)->SRB_Status,
(DWORD)DoneSRB);
return;
}
#endif
// **************************************************************************
// *
// * Procedure: WndProc()
// *
// **************************************************************************
#ifdef WIN32
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,
LPARAM lParam)
#else
long __far __pascal _export WndProc(HWND hwnd,UINT message,WPARAM
wParam,LPARAM lParam)
#endif
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
HMENU hMenu;
static short cxClient, cyClient;
int i=0;
WORD status;
#ifdef WIN32
SRB_ExecSCSICmd *SRBPtr;
#else
SRB_ExecSCSICmd6 far *SRBPtr;
#endif
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc,&tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight;
ReleaseDC(hwnd,hdc);
rect.top = 0;
return 0;
case WM_PAINT:
InvalidateRect(hwnd,NULL,TRUE);
hdc = BeginPaint(hwnd,&ps) ;
EndPaint (hwnd,&ps) ;
return 0 ;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
rect.right = LOWORD(lParam);
rect.bottom = HIWORD(lParam);
UpdateWindow(hwnd);
return 0;
case WM_COMMAND:
hMenu = GetMenu(hwnd);
switch (wParam)
{
case ID_FILE_EXIT:
SendMessage(hwnd,WM_CLOSE,0,0L);
return 0;
default:
// 10 = target #0
// 11 = target #1
// 12 = target #2
// 13 = target #3
// 14 = target #4
// 15 = target #5
// 16 = target #6
// 17 = target #7
// Toggle the SCSI target scan status (ENABLED/DISABELD)
if ((wParam >= 10 && wParam <= 17) ||
(wParam >= 20 && wParam <= 27))
{
status = GetMenuState(hMenu,wParam,MF_BYCOMMAND) & MF_CHECKED;
CheckMenuItem(hMenu,wParam,MF_BYCOMMAND | ((status) ? MF_UNCHECKED:MF_CHECKED));
}
return 0;
}
case WM_ASPIPOST:
#ifdef WIN32
SRBPtr = (PSRB_ExecSCSICmd)lParam;
#else
SRBPtr = (SRB_ExecSCSICmd6 far *)lParam;
#endif
DisplaySCSIID(hwnd,SRBPtr);
ScanNextTarget(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
When the post routine is called, this sample post handler will fill the wParam field with the status of ASPI command (SRB_Status) while the lParam field will contain a pointer to the SRB which has completed.