home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / PMFLOPPY.ZIP / PMFLOPPY.C < prev    next >
C/C++ Source or Header  |  1990-04-24  |  12KB  |  394 lines

  1. // pmfloppy.c
  2. // PM based disk utility.  Use separate threads for disk actions to prevent slowing
  3. // up PM too much.
  4.  
  5. #define INCL_PM
  6. #define INCL_BASE
  7. #define INCL_DOSERRORS
  8. #define INCL_DOSPROCESS
  9. #define INCL_DOSDEVIOCTL
  10. #define INCL_DOSSESMGR
  11. #define INCL_GPILCIDS
  12. #include <os2.h>
  13. #include <stdlib.h>
  14. #include <stdarg.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "pmfloppy.h"
  18.  
  19. // prototypes for current file
  20. MRESULT EXPENTRY ClientWndProc(HWND, USHORT, MPARAM, MPARAM);
  21. MRESULT Panic(PCH, USHORT);
  22. MRESULT DisplayStatus(HWND, MPARAM, MPARAM, PSZ);
  23. MRESULT DisplayDone(HWND , MPARAM, PSZ);
  24.  
  25. // prototypes from copydlgs.c
  26. extern MRESULT EXPENTRY ReadDlgProc(HWND, USHORT, MPARAM, MPARAM);
  27. extern MRESULT EXPENTRY WriteDlgProc(HWND, USHORT, MPARAM, MPARAM);
  28. extern MRESULT EXPENTRY FmtDlgProc(HWND, USHORT, MPARAM, MPARAM);
  29. extern MRESULT EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);
  30. extern MRESULT EXPENTRY QuitDlgProc(HWND, USHORT, MPARAM, MPARAM);
  31.  
  32. // prototypes from dskcpy.c
  33. extern VOID FAR readsource(USHORT);
  34. extern VOID FAR writetarget(USHORT);
  35. extern VOID FAR fmtdisk(USHORT);
  36.  
  37. /* GLOBAL VARIABLES */
  38.  
  39. // PM vbls
  40. HAB    hab;
  41. HMQ    hmq;
  42. HWND   hWndFrame ;
  43. static CHAR szClientClass[]="PMFloppy";
  44. ULONG  ctldata = FCF_STANDARD & ~FCF_TASKLIST;
  45. HWND   hWndClient;
  46. HWND   hwndDeskTop;
  47. QMSG   qmsg;
  48. LONG   CharHeight;
  49. LONG   CharWidth;
  50.  
  51. // User response vbls
  52. USHORT DriveActive;                // Bit map indicating active drives
  53. USHORT FormatOptions;              // Bit map indicating formatting choice
  54. USHORT usReadDrive;                // Drive to read from (from dialog box)
  55. CHAR   szReadDrive[] = "A:";       // Drive to read from (from dialog box)
  56. USHORT usWriteDrive;               // Drive to write to (from dialog box)
  57. CHAR   szWriteDrive[] = "A:";      // Drive to write to (from dialog box)
  58. USHORT usFmtDrive;                 // Drive to format (from dialog box)
  59. CHAR   szFmtDrive[] = "A:";        // Drive to format (from dialog box)
  60. CHAR   Volume[11];                 // Volume Name
  61.  
  62. // Thread vbls
  63. TID    CopyID;                     // Thread ID for the subprocess
  64. SEL    rgselStack;
  65.  
  66. // Disk handling vbls
  67. int    gotSource = FALSE;   /* Bool: Source disk has been read    */
  68.  
  69.  
  70. int cdecl main(void)
  71. {
  72.  
  73.   hab = WinInitialize(0);
  74.   hmq = WinCreateMsgQueue(hab, 0);
  75.   hwndDeskTop = WinQueryDesktopWindow(hab, NULL);
  76.  
  77.   if (!WinRegisterClass(hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0))
  78.     return(0);
  79.  
  80.   hWndFrame = WinCreateStdWindow(HWND_DESKTOP
  81.                      , WS_VISIBLE
  82.                , &ctldata
  83.                , szClientClass
  84.                , "Disk Utility"
  85.                , 0L
  86.                , NULL
  87.                , IDR_PMFLOPPY
  88.                , &hWndClient);
  89.  
  90.   if (hWndFrame != NULL)
  91.   {
  92.     while ( WinGetMsg(hab, &qmsg, NULL, 0, 0) )
  93.         WinDispatchMsg(hab, &qmsg);
  94.  
  95.     WinDestroyWindow(hWndFrame);
  96.   }
  97.  
  98.   WinDestroyMsgQueue(hmq);
  99.   WinTerminate(hab);
  100.  
  101.   DosExit(EXIT_PROCESS, 0);
  102. } /* main */
  103.  
  104.  
  105. // ClientWndProc - main window processing
  106. //
  107. //  note: UM messages are User-defined (in pmfloppy.h).
  108. //        all UM messages use mp2 to indicate the drive the message concerns,
  109. //        and mp1 is data specific to that message.  Then UM_xxxMSG is a 
  110. //        generic msg.  It is currently only used for DONE messages.  If I
  111. //        need more, set up some magic numbers and pass them through mp1. 
  112. //
  113. MRESULT EXPENTRY ClientWndProc(HWND hwnd
  114.                   , USHORT id
  115.                   , MPARAM mp1
  116.                   , MPARAM mp2)
  117. {
  118. HPS     hPS;
  119. HWND    hMenu;
  120. CHAR    szTxtBuf[40];
  121. USHORT  usDrive;
  122. int far *stkptr;
  123. RECTL   rctStart;
  124. FONTMETRICS fm;
  125.  
  126.   switch (id)
  127.   {
  128.     case WM_CREATE:
  129.       DriveActive = 0;
  130.       hPS = WinGetPS(hwnd);
  131.       GpiQueryFontMetrics(hPS, (long)sizeof(fm), &fm);
  132.       CharHeight = fm.lMaxBaselineExt;
  133.       CharWidth = fm.lMaxCharInc;
  134.       WinReleasePS(hPS);
  135.       break;
  136.  
  137.     case WM_PAINT:
  138.       hPS = WinGetPS(hwnd);
  139.       GpiErase(hPS);
  140.       WinReleasePS(hPS);
  141.       WinQueryUpdateRect(hwnd, &rctStart);
  142.       WinValidateRect(hwnd, &rctStart, FALSE);
  143.       break;
  144.  
  145.     case WM_COMMAND:
  146.       switch (COMMANDMSG(&id)->cmd)
  147.       {
  148.         case IDM_READ:
  149.           if (WinDlgBox(HWND_DESKTOP,hWndFrame,ReadDlgProc,NULL,READ_DLG,NULL))
  150.           {
  151.             // send off thread to read
  152.             DosAllocSeg(STACK_SIZE, &rgselStack, 0);
  153.             stkptr = (int far *)MAKEP(rgselStack, STACK_SIZE);
  154.             *(--stkptr) = (int) szReadDrive[0];
  155.  
  156.             if (DosCreateThread(readsource, &(CopyID), (PBYTE)stkptr) ) 
  157.             {
  158.                     WinMessageBox(HWND_DESKTOP, hWndFrame, "Creating a thread failed."
  159.                              , "Drive Read"
  160.                              , 0, MB_OK | MB_ICONEXCLAMATION);
  161.                     DosFreeSeg(rgselStack);
  162.                     return FALSE;
  163.             } /* if can't create one thread. */
  164.             DriveActive |= usReadDrive;
  165.           }
  166.           break;
  167.  
  168.         case IDM_WRITE:
  169.           // put up dialog, return drive indicators, format type
  170.           if (WinDlgBox(HWND_DESKTOP,hWndFrame,WriteDlgProc,NULL,WRITE_DLG,NULL))
  171.           {
  172.             // send off thread to write
  173.             DosAllocSeg(STACK_SIZE, &rgselStack, 0);
  174.             stkptr = (int far *)MAKEP(rgselStack, STACK_SIZE);
  175.             *(--stkptr) = (int) szWriteDrive[0];
  176.  
  177.             if (DosCreateThread(writetarget, &(CopyID), (PBYTE)stkptr) ) 
  178.             {
  179.                     WinMessageBox(HWND_DESKTOP, hWndFrame, "Creating a thread failed."
  180.                              , "Drive Write"
  181.                              , 0, MB_OK | MB_ICONEXCLAMATION);
  182.                     DosFreeSeg(rgselStack);
  183.                     return FALSE;
  184.             } /* if can't create one thread. */
  185.             DriveActive |= usWriteDrive;
  186.           }
  187.           break;
  188.  
  189.         case IDM_FORMAT:
  190.           // put up dialog, return drive indicators, format type
  191.           if (WinDlgBox(HWND_DESKTOP,hWndFrame,FmtDlgProc,NULL,FORMAT_DLG,NULL))
  192.           {
  193.             // send off thread to format
  194.             DosAllocSeg(STACK_SIZE, &rgselStack, 0);
  195.             stkptr = (int far *)MAKEP(rgselStack, STACK_SIZE);
  196.             *(--stkptr) = (int) szFmtDrive[0];
  197.  
  198.             if (DosCreateThread(fmtdisk, &(CopyID), (PBYTE)stkptr) ) 
  199.             {
  200.                     WinMessageBox(HWND_DESKTOP, hWndFrame, "Creating a thread failed."
  201.                              , "Drive Format"
  202.                              , 0, MB_OK | MB_ICONEXCLAMATION);
  203.                     DosFreeSeg(rgselStack);
  204.                     return FALSE;
  205.             } /* if can't create one thread. */
  206.             DriveActive |= usFmtDrive;
  207.           }
  208.           break;
  209.  
  210.         case IDM_ABOUT:
  211.           WinDlgBox(HWND_DESKTOP,hWndFrame,AboutDlgProc,NULL,ABOUT_DLG,NULL);
  212.           break;
  213.  
  214.         case IDM_EXIT:
  215.           WinPostMsg(hWndFrame, WM_CLOSE, NULL, NULL);
  216.           break;
  217.       }
  218.       break;
  219.  
  220.     case WM_INITMENU:
  221.       //set the allowable menu choices.
  222.       hMenu = WinWindowFromID(hWndFrame,FID_MENU);
  223.  
  224.       // If we are reading, disable the read option
  225.       WinSendMsg(hMenu,MM_SETITEMATTR,
  226.         MPFROM2SHORT(IDM_READ,TRUE),
  227.         MPFROM2SHORT(MIA_DISABLED,(DriveActive && usReadDrive) ? MIA_DISABLED : 0));
  228.  
  229.       // If we don't have anything to write, disable the write menu
  230.       WinSendMsg(hMenu,MM_SETITEMATTR,
  231.         MPFROM2SHORT(IDM_WRITE,TRUE),
  232.         MPFROM2SHORT(MIA_DISABLED,gotSource ? 0 : MIA_DISABLED));
  233.  
  234.       // until format is working, leave it disabled.
  235.       WinSendMsg(hMenu,MM_SETITEMATTR,
  236.         MPFROM2SHORT(IDM_FORMAT,TRUE),
  237.         MPFROM2SHORT(MIA_DISABLED,MIA_DISABLED));
  238.       break;
  239.  
  240.     case UM_READSTATUS:
  241.       DisplayStatus(hwnd,mp1,mp2,"read");
  242.       break;
  243.  
  244.     case UM_READMSG:
  245.       DisplayDone(hwnd, mp2, "Read");
  246.       break;
  247.  
  248.     case UM_READERROR:
  249.       usDrive = SHORT1FROMMP(mp2);
  250.       sprintf(szTxtBuf,"Read Error on drive %c", (CHAR)usDrive);
  251.       DriveActive &= ~((usDrive - (USHORT)'A') + 1);
  252.       Panic(szTxtBuf,SHORT1FROMMP(mp1));
  253.       break;
  254.  
  255.     case UM_WRITESTATUS:
  256.       DisplayStatus(hwnd,mp1,mp2,"written");
  257.       break;
  258.  
  259.     case UM_WRITEMSG:
  260.       DisplayDone(hwnd, mp2, "Write");
  261.       break;
  262.  
  263.     case UM_WRITEERROR:
  264.       usDrive = SHORT1FROMMP(mp2);
  265.       sprintf(szTxtBuf,"Write Error on drive %c", (CHAR)usDrive);
  266.       DriveActive &= ~((usDrive - (USHORT)'A') + 1);
  267.       Panic(szTxtBuf,SHORT1FROMMP(mp1));
  268.       break;
  269.  
  270.     case UM_FMTSTATUS:
  271.       DisplayStatus(hwnd,mp1,mp2,"formatted");
  272.       break;
  273.  
  274.     case UM_FMTMSG:
  275.       DisplayDone(hwnd, mp2, "Format");
  276.       break;
  277.  
  278.     case UM_FMTERROR:
  279.       usDrive = SHORT1FROMMP(mp2);
  280.       sprintf(szTxtBuf,"Format Error on drive %c", (CHAR)usDrive);
  281.       DriveActive &= ~((usDrive - (USHORT)'A') + 1);
  282.       Panic(szTxtBuf,SHORT1FROMMP(mp1));
  283.       break;
  284.  
  285.     case WM_CLOSE:
  286.       if (DriveActive)
  287.       {
  288.         if (!WinDlgBox(HWND_DESKTOP,hWndFrame,QuitDlgProc,NULL,QUIT_DLG,NULL))
  289.         break;
  290.       }
  291.       // else just fall through to default to get to the default proc
  292.     default:
  293.       return(WinDefWindowProc(hwnd, id, mp1, mp2));
  294.  
  295.   } /* switch id */
  296.  
  297.   return 0L;
  298.  
  299. } /* clientwndproc */
  300.  
  301.  
  302. //  Panic  --  Put up a message box with an error message.
  303. //
  304. //  Inputs:   pszCaption  --  Caption text for message box
  305. //
  306. //  Returns:  1L, for error signalling from window procedures.
  307. MRESULT Panic(PCH pszCaption,USHORT ErrorNum)
  308. {
  309. HWND hwndCurFocus;
  310. CHAR buf[1024];
  311. USHORT cbBuf;
  312.  
  313.   if (ErrorNum == DSKCPY_ERROR_WRONG_FORMAT)
  314.     sprintf(buf, "Error - target disk incorrect format");
  315.   else if (DosGetMessage(NULL, 0, buf, 1024, ErrorNum, "oso001.msg", &cbBuf))
  316.   {
  317.     sprintf(buf, "SYS%04d: error text unavailable", ErrorNum);
  318.     cbBuf = 31;
  319.   }
  320.   buf[cbBuf] = (char)0;
  321.  
  322. //  if (hf) DosClose(hf);
  323.  
  324.   hwndCurFocus = WinQueryFocus(HWND_DESKTOP, FALSE);
  325.   WinAlarm(HWND_DESKTOP, WA_NOTE);
  326.  
  327.   WinMessageBox(HWND_DESKTOP, hWndFrame, buf, pszCaption,
  328.           0, MB_OK | MB_ICONEXCLAMATION);
  329.  
  330.   return(1);
  331. } // panic
  332.  
  333.  
  334. // DisplayStatus - Display the status for the drive in the PS
  335. //
  336. //  in:  mp1,mp2 message parameters from the wndproc
  337. //       hwnd    window handle to display on
  338. //       op      operation (eg read, write)
  339. //
  340. MRESULT DisplayStatus(HWND hwnd, MPARAM mp1, MPARAM mp2, PSZ op)
  341. {
  342. USHORT  usPos;
  343. USHORT  usTotal;
  344. USHORT  usDrive;
  345. RECTL   rctStart;
  346. CHAR    szPct[3];
  347. HPS     hPS;
  348. CHAR    szTxtBuf[40];
  349.  
  350.   usPos = SHORT1FROMMP(mp1);
  351.   usTotal = SHORT2FROMMP(mp1);
  352.   usDrive = SHORT1FROMMP(mp2);
  353.   rctStart.xLeft = 5L;
  354.   rctStart.xRight = 5L + (CharWidth * 40);
  355.   rctStart.yBottom = ((usDrive - (USHORT)'A') * CharHeight) + 5;
  356.   rctStart.yTop = rctStart.yBottom + CharHeight;
  357.   itoa((USHORT)(((float)usPos/(float)usTotal)*100.0),szPct,10);
  358.   hPS = WinGetPS(hwnd);
  359.   sprintf(szTxtBuf,"%s%% of disk %s (Drive %c)",szPct, op, (CHAR)usDrive);
  360.   WinDrawText(hPS, -1, szTxtBuf, &rctStart, CLR_NEUTRAL, CLR_BACKGROUND,
  361.               DT_LEFT | DT_ERASERECT);
  362.   WinReleasePS(hPS);
  363.   return 0;
  364. }
  365.  
  366.  
  367. // DisplayDone - Display an operation complete
  368. //
  369. //  in:  mp2     message parameters from the wndproc
  370. //       hwnd    window handle to display on
  371. //       op      operation (eg read, write)
  372. //
  373. MRESULT DisplayDone(HWND hwnd, MPARAM mp2, PSZ op)
  374. {
  375. USHORT  usDrive;
  376. RECTL   rctStart;
  377. HPS     hPS;
  378. CHAR    szTxtBuf[40];
  379.  
  380.   usDrive = SHORT1FROMMP(mp2);
  381.   rctStart.xLeft = 5L;
  382.   rctStart.xRight = 5L + (CharWidth * 40);
  383.   rctStart.yBottom = ((usDrive - (USHORT)'A') * CharHeight) + 5;
  384.   rctStart.yTop = rctStart.yBottom + CharHeight;
  385.   WinAlarm(HWND_DESKTOP, WA_NOTE);
  386.   hPS = WinGetPS(hwnd);
  387.   sprintf(szTxtBuf,"%s complete (Drive %c)", op, (CHAR)usDrive);
  388.   WinDrawText(hPS, -1, szTxtBuf, &rctStart, CLR_NEUTRAL, CLR_BACKGROUND,
  389.               DT_LEFT | DT_ERASERECT);
  390.   WinReleasePS(hPS);
  391.   DriveActive &= ~((usDrive - (USHORT)'A') + 1);
  392.   return 0;
  393. }
  394.