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.