Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

WINBUILD/archlib.c

Go to the documentation of this file.
00001 /*
00002  *      This program is free software; you can redistribute it and/or
00003  *      modify it under the terms of the GNU General Public License
00004  *      as published by the Free Software Foundation; either version
00005  *      2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 1999-2001 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
00008  *  Copyright 2001-2005 Spiro Trikaliotis
00009  *
00010 */
00011 
00021 #include <windows.h>
00022 #include <windowsx.h>
00023 
00024 #include <mmsystem.h>
00025 
00027 #define DBG_USERMODE
00028 
00030 #define DBG_DLL
00031 
00033 #define DBG_PROGNAME "OPENCBM.DLL"
00034 
00036 #define DBG_IS_DEBUG_C
00037 
00038 #include "debug.h"
00039 
00040 #include <winioctl.h>
00041 #include "cbmioctl.h"
00042 
00043 #include <stdlib.h>
00044 
00046 #define DLL
00047 #include "i_opencbm.h"
00048 #include "archlib.h"
00049 
00050 
00072 static void
00073 fastschedule_start(void)
00074 {
00075     FUNC_ENTER();
00076 
00077     if (timeBeginPeriod(1) != TIMERR_NOERROR)
00078     {
00079         DBG_WARN((DBG_PREFIX "Unable to decrease scheduling period."));
00080     }
00081 
00082     FUNC_LEAVE();
00083 }
00084 
00090 static void
00091 fastschedule_stop(void)
00092 {
00093     FUNC_ENTER();
00094 
00095     if (timeEndPeriod(1) != TIMERR_NOERROR)
00096     {
00097         DBG_WARN((DBG_PREFIX "Unable to restore scheduling period."));
00098     }
00099 
00100     FUNC_LEAVE();
00101 }
00102 
00103 
00128 BOOL
00129 opencbm_init(IN HANDLE Module, IN DWORD Reason, IN LPVOID Reserved)
00130 {
00131     static BOOL bIsOpen = FALSE;
00132     BOOLEAN Status = TRUE;
00133 
00134     FUNC_ENTER();
00135 
00136 #if DBG
00137 
00138     if (Reason == DLL_PROCESS_ATTACH)
00139     {
00140         // Read the debugging flags from the registry
00141 
00142         cbm_i_get_debugging_flags();
00143     }
00144 
00145 #endif
00146 
00147     /* make sure the definitions in opencbm.h and cbmioctl.h
00148      * match each other! 
00149      * Since we are the only instance which includes both files,
00150      * we are the only one which can ensure this.
00151      */
00152 
00153     DBG_ASSERT(IEC_LINE_CLOCK == IEC_CLOCK);
00154     DBG_ASSERT(IEC_LINE_RESET == IEC_RESET);
00155     DBG_ASSERT(IEC_LINE_DATA == IEC_DATA);
00156     DBG_ASSERT(IEC_LINE_ATN == IEC_ATN);
00157 
00158     switch (Reason) 
00159     {
00160         case DLL_PROCESS_ATTACH:
00161 
00162             if (IsDriverStartedAutomatically())
00163             {
00164                 // the driver is started automatically, do not try
00165                 // to start it
00166 
00167                 Status = TRUE;
00168             }
00169             else
00170             {
00171                 if (bIsOpen)
00172                 {
00173                     DBG_ERROR((DBG_PREFIX "No multiple instances are allowed!"));
00174                     Status = FALSE;
00175                 }
00176                 else
00177                 {
00178                     Status  = TRUE;
00179                     bIsOpen = cbm_i_driver_start();
00180                 }
00181             }
00182 
00183             /* If the DLL loaded successfully, ask for fast scheduling */
00184             if (Status)
00185             {
00186                 fastschedule_start();
00187             }
00188             break;
00189 
00190         case DLL_PROCESS_DETACH:
00191 
00192             if (IsDriverStartedAutomatically())
00193             {
00194                 // the driver is started automatically, do not try
00195                 // to stop it
00196 
00197                 Status = TRUE;
00198             }
00199             else
00200             {
00201                 if (!bIsOpen)
00202                 {
00203                     DBG_ERROR((DBG_PREFIX "Driver is not running!"));
00204                     Status = FALSE;
00205                 }
00206                 else
00207                 {
00208                     // it is arguable if the driver should be stopped
00209                     // whenever the DLL is unloaded.
00210 
00211                     cbm_i_driver_stop();
00212                     bIsOpen = FALSE;
00213                 }
00214             }
00215 
00216             /* If the DLL unloaded successfully, we do not need fast scheduling anymore. */
00217             if (Status)
00218             {
00219                 fastschedule_stop();
00220             }
00221             break;
00222 
00223         default:
00224             break;
00225 
00226     }
00227 
00228     FUNC_LEAVE_BOOL(Status);
00229 }
00230 
00250 BOOL CBMAPIDECL
00251 cbm_i_driver_install(OUT PULONG Buffer, IN ULONG BufferLen)
00252 {
00253     FUNC_ENTER();
00254 
00255     FUNC_LEAVE_INT(cbm_i_i_driver_install(Buffer, BufferLen));
00256 }
00257 
00258 
00283 void
00284 cbmarch_lock(CBM_FILE HandleDevice)
00285 {
00286     FUNC_ENTER();
00287 
00288     cbm_ioctl(HandleDevice, CBMCTRL(PARPORT_LOCK), NULL, 0, NULL, 0);
00289 
00290     FUNC_LEAVE();
00291 }
00292 
00310 void
00311 cbmarch_unlock(CBM_FILE HandleDevice)
00312 {
00313     FUNC_ENTER();
00314 
00315     cbm_ioctl(HandleDevice, CBMCTRL(PARPORT_UNLOCK), NULL, 0, NULL, 0);
00316 
00317     FUNC_LEAVE();
00318 }
00319 
00344 int
00345 cbmarch_raw_write(CBM_FILE HandleDevice, const void *Buffer, size_t Count)
00346 {
00347     DWORD BytesWritten;
00348 
00349     FUNC_ENTER();
00350 
00351     WriteFile(
00352         HandleDevice,
00353         Buffer,
00354         Count,
00355         &BytesWritten,
00356         NULL
00357         );
00358 
00359     FUNC_LEAVE_INT(BytesWritten);
00360 }
00361 
00385 int
00386 cbmarch_raw_read(CBM_FILE HandleDevice, void *Buffer, size_t Count)
00387 {
00388     DWORD bytesToRead = Count;
00389     DWORD bytesRead;
00390 
00391     FUNC_ENTER();
00392 
00393     ReadFile(
00394         HandleDevice,
00395         Buffer,
00396         bytesToRead,
00397         &bytesRead,
00398         NULL
00399         );
00400 
00401     FUNC_LEAVE_INT(bytesRead);
00402 }
00403 
00404 
00405 
00429 int
00430 cbmarch_listen(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00431 {
00432     CBMT_LISTEN_IN parameter;
00433     int returnValue;
00434 
00435     FUNC_ENTER();
00436 
00437     parameter.PrimaryAddress = DeviceAddress;
00438     parameter.SecondaryAddress = SecondaryAddress;
00439 
00440     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(LISTEN), &parameter, sizeof(parameter), NULL, 0)
00441         ? 0 : 1;
00442 
00443     FUNC_LEAVE_INT(returnValue);
00444 }
00445 
00469 int
00470 cbmarch_talk(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00471 {
00472     CBMT_TALK_IN parameter;
00473     int returnValue;
00474 
00475     FUNC_ENTER();
00476 
00477     parameter.PrimaryAddress = DeviceAddress;
00478     parameter.SecondaryAddress = SecondaryAddress;
00479 
00480     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(TALK), &parameter, sizeof(parameter), NULL, 0)
00481         ? 0 : 1;
00482 
00483     FUNC_LEAVE_INT(returnValue);
00484 }
00485 
00507 int
00508 cbmarch_open(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00509 {
00510     CBMT_OPEN_IN parameter;
00511     int returnValue;
00512 
00513     FUNC_ENTER();
00514 
00515     parameter.PrimaryAddress = DeviceAddress;
00516     parameter.SecondaryAddress = SecondaryAddress;
00517 
00518     if (cbm_ioctl(HandleDevice, CBMCTRL(OPEN), &parameter, sizeof(parameter), NULL, 0))
00519     {
00520         returnValue = 0;
00521     }
00522     else
00523     {
00524         returnValue = -1;
00525     }
00526 
00527     FUNC_LEAVE_INT(returnValue);
00528 }
00529 
00551 int
00552 cbmarch_close(CBM_FILE HandleDevice, __u_char DeviceAddress, __u_char SecondaryAddress)
00553 {
00554     CBMT_CLOSE_IN parameter;
00555     int returnValue;
00556 
00557     FUNC_ENTER();
00558 
00559     parameter.PrimaryAddress = DeviceAddress;
00560     parameter.SecondaryAddress = SecondaryAddress;
00561 
00562     returnValue = 
00563         cbm_ioctl(HandleDevice, CBMCTRL(CLOSE), &parameter, sizeof(parameter), NULL, 0)
00564         ? 0 : 1;
00565 
00566     FUNC_LEAVE_INT(returnValue);
00567 }
00568 
00589 int
00590 cbmarch_unlisten(CBM_FILE HandleDevice)
00591 {
00592     int returnValue;
00593 
00594     FUNC_ENTER();
00595 
00596     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(UNLISTEN), NULL, 0, NULL, 0) ? 0 : 1;
00597 
00598     FUNC_LEAVE_INT(returnValue);
00599 }
00600 
00621 int
00622 cbmarch_untalk(CBM_FILE HandleDevice)
00623 {
00624     int returnValue;
00625 
00626     FUNC_ENTER();
00627 
00628     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(UNTALK), NULL, 0, NULL, 0) ? 0 : 1;
00629 
00630     FUNC_LEAVE_INT(returnValue);
00631 }
00632 
00633 
00654 int
00655 cbmarch_get_eoi(CBM_FILE HandleDevice)
00656 {
00657     CBMT_GET_EOI_OUT result;
00658 
00659     FUNC_ENTER();
00660 
00661     cbm_ioctl(HandleDevice, CBMCTRL(GET_EOI), NULL, 0, &result, sizeof(result));
00662 
00663     FUNC_LEAVE_INT(result.Decision);
00664 }
00665 
00681 int
00682 cbmarch_clear_eoi(CBM_FILE HandleDevice)
00683 {
00684     int returnValue;
00685 
00686     FUNC_ENTER();
00687 
00688     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(CLEAR_EOI), NULL, 0, NULL, 0);
00689 
00690     FUNC_LEAVE_INT(returnValue);
00691 }
00692 
00714 int
00715 cbmarch_reset(CBM_FILE HandleDevice)
00716 {
00717     USHORT returnValue;
00718 
00719     FUNC_ENTER();
00720 
00721     returnValue = cbm_ioctl(HandleDevice, CBMCTRL(RESET), NULL, 0, NULL, 0) ? 0 : 1;
00722 
00723     FUNC_LEAVE_INT(returnValue);
00724 }
00725 
00726 
00727 /*-------------------------------------------------------------------*/
00728 /*--------- LOW-LEVEL PORT ACCESS -----------------------------------*/
00729 
00751 __u_char
00752 cbmarch_pp_read(CBM_FILE HandleDevice)
00753 {
00754     CBMT_PP_READ_OUT result;
00755 
00756     FUNC_ENTER();
00757 
00758     cbm_ioctl(HandleDevice, CBMCTRL(PP_READ), NULL, 0, &result, sizeof(result));
00759 
00760     FUNC_LEAVE_UCHAR(result.Byte);
00761 }
00762 
00786 void
00787 cbmarch_pp_write(CBM_FILE HandleDevice, __u_char Byte)
00788 {
00789     CBMT_PP_WRITE_IN parameter;
00790 
00791     FUNC_ENTER();
00792 
00793     parameter.Byte = Byte;
00794 
00795     cbm_ioctl(HandleDevice, CBMCTRL(PP_WRITE), &parameter, sizeof(parameter), NULL, 0);
00796 
00797     FUNC_LEAVE();
00798 }
00799 
00821 int
00822 cbmarch_iec_poll(CBM_FILE HandleDevice)
00823 {
00824     CBMT_IEC_POLL_OUT result;
00825 
00826     FUNC_ENTER();
00827 
00828     cbm_ioctl(HandleDevice, CBMCTRL(IEC_POLL), NULL, 0, &result, sizeof(result));
00829 
00830     FUNC_LEAVE_INT(result.Line);
00831 }
00832 
00833 
00852 void
00853 cbmarch_iec_set(CBM_FILE HandleDevice, int Line)
00854 {
00855     CBMT_IEC_SET_IN parameter;
00856 
00857     FUNC_ENTER();
00858  
00859     parameter.Line = (UCHAR) Line;
00860 
00861     cbm_ioctl(HandleDevice, CBMCTRL(IEC_SET), &parameter, sizeof(parameter), NULL, 0);
00862 
00863     FUNC_LEAVE();
00864 }
00865 
00884 void
00885 cbmarch_iec_release(CBM_FILE HandleDevice, int Line)
00886 {
00887     CBMT_IEC_RELEASE_IN parameter;
00888 
00889     FUNC_ENTER();
00890 
00891     parameter.Line = (UCHAR) Line;
00892 
00893     cbm_ioctl(HandleDevice, CBMCTRL(IEC_RELEASE), &parameter, sizeof(parameter), NULL, 0);
00894 
00895     FUNC_LEAVE();
00896 }
00897 
00925 void
00926 cbmarch_iec_setrelease(CBM_FILE HandleDevice, int Set, int Release)
00927 {
00928     CBMT_IEC_SETRELEASE_IN parameter;
00929 
00930     FUNC_ENTER();
00931  
00932     parameter.State = (UCHAR) Set;
00933     parameter.Line = (UCHAR) Release;
00934 
00935     cbm_ioctl(HandleDevice, CBMCTRL(IEC_SETRELEASE), &parameter, sizeof(parameter), NULL, 0);
00936 
00937     FUNC_LEAVE();
00938 }
00939 
00966 int
00967 cbmarch_iec_wait(CBM_FILE HandleDevice, int Line, int State)
00968 {
00969 /*
00970     CBMT_IEC_WAIT_IN parameter;
00971     CBMT_IEC_WAIT_OUT result;
00972 
00973     FUNC_ENTER();
00974 
00975     parameter.Line = (UCHAR) Line;
00976     parameter.State = (UCHAR) State;
00977 
00978     cbm_ioctl(HandleDevice, CBMCTRL(IEC_WAIT), 
00979         &parameter, sizeof(parameter), 
00980         &result, sizeof(result));
00981 
00982     FUNC_LEAVE_INT(result.Line);
00983 */
00984     int state;
00985 
00986     FUNC_ENTER();
00987     if (State)
00988     {
00989         while((state = cbm_iec_get(HandleDevice, Line)) == 0)
00990             ;
00991     }
00992     else
00993     {
00994         while((state = cbm_iec_get(HandleDevice, Line)) != 0)
00995             ;
00996     }
00997 
00998     FUNC_LEAVE_INT(state);
00999 }
01000 
01001 #if DBG
01002 
01011 int CBMAPIDECL
01012 cbm_get_debugging_buffer(CBM_FILE HandleDevice, char *buffer, size_t len)
01013 {
01014     FUNC_ENTER();
01015 
01016     cbm_ioctl(HandleDevice, CBMCTRL(I_READDBG), NULL, 0, buffer, len);
01017 
01018     FUNC_LEAVE_INT(0);
01019 }
01020 
01021 #endif // #if DBG

Generated on Sun Apr 30 18:45:42 2006 for opencbm by  doxygen 1.4.2