Using Callback

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.