home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l231 / 3.ddi / SAMPLES / WINDLL / SYSINFO.AS$ / SYSINFO
Encoding:
Text File  |  1992-11-12  |  13.2 KB  |  457 lines

  1. ;* SYSINFO.ASM
  2. ;*
  3. ;* Assembly-language source for example DLL.  SYSINFO.DLL contains three
  4. ;* library routines, which any Windows process can call:
  5. ;*
  6. ;*    GetSysTime    Returns a ptr to a string "hh:mm:ss xx" where
  7. ;*            hh:mm:ss = hour:min:sec.  If country not USA,
  8. ;*            string is 24-hour time.  Otherwise, string is
  9. ;*            12-hour American format, with xx = "am" or "pm".
  10. ;*
  11. ;*    GetSysDate    Returns a ptr to a string "day, month xx, xxxx".
  12. ;*            day and month are translated to one of six
  13. ;*            different languages:  English, French, Spanish,
  14. ;*            German, Italian, or Swedish.
  15. ;*
  16. ;*    GetSysInfo    Returns a ptr to a structure containing various
  17. ;*            data from the the BIOS data areas.
  18.  
  19.  
  20. .MODEL    medium, pascal, farstack
  21. .286
  22.  
  23. INCLUDE dll.inc
  24. INCLUDE    win.inc
  25.  
  26. .DATA
  27. TaskHead    BYTE    16 DUP(0)        ; 1st paragraph reserved
  28.                         ;   for Windows task header
  29.  
  30. DayEng        STRZ    'Sunday', 0,       'Monday', 0,        'Tuesday', 0
  31.         STRZ    'Wednesday', 0,       'Thursday', 0,    'Friday', 0
  32.         STRZ    'Saturday', 0
  33.  
  34. DayFre        STRZ    'dimanche', 0,       'lundi', 0,        'mardi', 0
  35.         STRZ    'mercredi', 0,       'jeudi', 0,        'vendredi', 0
  36.         STRZ    'samedi', 0
  37.  
  38. DaySpa        STRZ    'domingo', 0,       'lunes', 0,        'martes', 0
  39.         STRZ    'miércoles', 0,       'jueves', 0,        'viernes', 0
  40.         STRZ    'sábado', 0
  41.  
  42. DayGer        STRZ    'Sonntag', 0,       'Montag', 0,        'Dienstag', 0
  43.         STRZ    'Mittwoch', 0,       'Donnerstag', 0,    'Freitag', 0
  44.         STRZ    'Samstag', 0
  45.  
  46. DayIta        STRZ    'domenica', 0,       'lunedì', 0,        'martedì', 0
  47.         STRZ    'mercoledì', 0,       'giovedì', 0,    'venerdì', 0
  48.         STRZ    'sabato', 0
  49.  
  50. DaySwe        STRZ    'söndag', 0,       'mandag', 0,        'tisdag', 0
  51.         STRZ    'onsdag', 0,       'torsdag', 0,    'fredag', 0
  52.         STRZ    'lördag', 0
  53.  
  54. MonEng        STRZ    'January', 0,       'February', 0,    'March', 0
  55.         STRZ    'April', 0,       'May', 0,        'June', 0
  56.         STRZ    'July', 0,       'August', 0,        'September', 0
  57.         STRZ    'October', 0,       'November', 0,    'December', 0
  58.  
  59. MonFre        STRZ    'janvier', 0,       'fevrier', 0,    'mars', 0
  60.         STRZ    'avril', 0,       'mai', 0,        'juin', 0
  61.         STRZ    'juillet', 0,       'août', 0,        'septembre', 0
  62.         STRZ    'octobre', 0,       'novembre', 0,    'décembre', 0
  63.  
  64. MonSpa        STRZ    'enero', 0,       'febrero', 0,    'marzo', 0
  65.         STRZ    'abril', 0,       'mayo', 0,        'junio', 0
  66.         STRZ    'julio', 0,       'agosto', 0,        'septiembre', 0
  67.         STRZ    'octubre', 0,       'noviembre', 0,    'diciembre', 0
  68.  
  69. MonGer        STRZ    'Januar', 0,       'Februar', 0,    'März', 0
  70.         STRZ    'April', 0,       'Mai', 0,        'Juni', 0
  71.         STRZ    'Juli', 0,       'August', 0,        'September', 0
  72.         STRZ    'Oktober', 0,       'November', 0,    'Dezember', 0
  73.  
  74. MonIta        STRZ    'gennaio', 0,       'febbraio', 0,    'marzo', 0
  75.         STRZ    'aprile', 0,       'maggio', 0,        'giugno', 0
  76.         STRZ    'luglio', 0,       'agosto', 0,        'septtembre', 0
  77.         STRZ    'ottobre', 0,       'nobembre', 0,    'dicembre', 0
  78.  
  79. MonSwe        STRZ    'januari', 0,       'februari', 0,    'mars', 0
  80.         STRZ    'april', 0,       'maj', 0,        'juni', 0
  81.         STRZ    'juli', 0,       'augusti', 0,    'september', 0
  82.         STRZ    'oktober', 0,       'november', 0,    'december', 0
  83.  
  84. Sect        STRZ    'intl', 0        ; Section in WIN.INI file
  85. Ent1        STRZ    'sLanguage', 0        ; Windows language
  86. Ent2        STRZ    'sTime', 0        ; Windows time separator
  87. Language    STRZ    'ENU', 0        ; Default language (Amer Eng)
  88. Separator    STRZ    ':', 0            ; Default time separator
  89.  
  90. sys        SYSINFO<>            ; System info structure
  91. time        QUALTIME<>            ; Time structure hour:min:sec
  92. Date        STRZ    32 DUP(0)        ; Full date string
  93.  
  94. ; indx = array index for days and months:
  95. ;    0 = English        4 = Spanish         8 = Italian
  96. ;    2 = French        6 = German        10 = Swedish
  97. indx        WORD    0
  98. days        NPSTR    DayEng, DayFre, DaySpa, DayGer, DayIta, DaySwe
  99. months        NPSTR    MonEng, MonFre, MonSpa, MonGer, MonIta, MonSwe
  100.  
  101. ; Array of processor types
  102. procs        BYTE    WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486
  103.  
  104.  
  105. .CODE
  106. LibMain        PROC    FAR PASCAL
  107.  
  108. ;
  109. ; Get international language
  110. ;
  111.         INVOKE    GetProfileString, ADDR Sect, ADDR Ent1, ADDR Language,
  112.                       ADDR Language, SIZEOF Language
  113. ;
  114. ; Get time separator char
  115. ;
  116.         INVOKE    GetProfileString, ADDR Sect, ADDR Ent2, ADDR Separator,
  117.                       ADDR Separator, SIZEOF Separator
  118.  
  119.         mov    al, Separator        ; AL = time separator char
  120.         mov    time.cSep1, al        ; Separator char is same
  121.         mov    time.cSep2, al        ;   between hh:mm and mm:ss
  122.         sub    bx, bx            ; BX = language index
  123.         mov    ax, WORD PTR Language    ; AX = 1st two letters of lang
  124.         and    ax, 5F5Fh        ; Capitalize both letters
  125.         .IF ( ax == FRENCH )
  126.         mov    bl, 2            ; If French, index = 2
  127.         .ENDIF
  128.         .IF ( ax == SPANISH )
  129.         mov    bl, 4            ; If Spanish, index = 4
  130.         .ENDIF
  131.         .IF ( ax == GERMAN )
  132.         mov    bl, 6            ; If German, index = 6
  133.         .ENDIF
  134.         .IF ( ax == ITALIAN )
  135.         mov    bl, 8            ; If Italian, index = 8
  136.         .ENDIF
  137.         .IF ( ax == SWEDISH )
  138.         mov    bl, 10            ; If Swedish, index = 10
  139.         .ENDIF
  140.  
  141.         mov    indx, bx        ; Initialize indx
  142.         ret                ; Return to LibEntry
  143.  
  144. LibMain        ENDP
  145.  
  146.  
  147.  
  148. ; Internal (non-exported) routines
  149. ;---------------------------------
  150.  
  151. ;* IntToAsc
  152. ;*
  153. ;* Converts integer in AL to ASCII digits.  Reverses digits on exit,
  154. ;* so '12' becomes '21'.  This allows caller to write the result to
  155. ;* memory as a word value.
  156. ;*
  157. ;* Entry:    AX    = binary digit 0-9,999
  158. ;* Return:    DX:AX    = ASCII chars
  159.  
  160. IntToAsc    PROC NEAR USES cx
  161.         cwd            ; Zero DX register
  162.         mov    cx, 100        ; Divide AX by 100, yields
  163.         div    cx        ;   AX = quotient, DX = remainder
  164.         aam            ; Make digits unpacked BCD
  165.         or    ax, '00'    ; Convert to ASCII digits
  166.         xchg    ah, al        ; Reverse digits to make big-ended
  167.         xchg    dx, ax        ; Do same thing for DX
  168.         aam
  169.         or    ax, '00'
  170.         xchg    ah, al        ; Reverse digits to make big-ended
  171.         ret            ; Return DX:AX = ASCII number
  172. IntToAsc    ENDP
  173.  
  174.  
  175.  
  176. ; Exported library routines
  177. ;--------------------------
  178. OPTION    PROLOGUE:None            ; Disable automatic prolog/epilog
  179. OPTION    EPILOGUE:None            ;   generation for DLL routines
  180.  
  181. ;* GetSysTime
  182. ;*
  183. ;* Places qualified time in 12-byte ASCIIZ string "hh:mm:ss xx", where
  184. ;* hh:mm:ss = hour:min:sec.  If indx > 0 (indicating country not USA),
  185. ;* string is 24-hour international time.  Otherwise, string is 12-hour
  186. ;* American format, and xx = "am" or "pm".
  187. ;*
  188. ;* Entry:    none
  189. ;* Return:    DX:AX = far pointer to ASCIIZ time string
  190.  
  191. GetSysTime    PROC    FAR EXPORT
  192.  
  193.         Prolog                ; Prologue macro
  194.         mov    ah, 2Ch            ; DOS service 2Ch
  195.         call    DOS3Call        ; Get System Time
  196.         mov    ax, '  '        ; Assume xx = blank
  197.         .IF (!indx)            ; If language = English,
  198.         mov    ax, 'ma'        ;   assume xx = 'am'
  199.         .IF (ch >= 12)            ; If afternoon, and if after
  200.         .IF    !zero?            ;   1:00 pm, reset hour
  201.         sub    ch, 12            ;   in CH to 12-hour clock
  202.         .ENDIF
  203.         mov    al, 'p'            ; Also set xx = 'pm'
  204.         .ENDIF
  205.         .ENDIF
  206.         push    dx            ; Save seconds
  207.         mov    WORD PTR time.szTail, ax; Place 'am', 'pm', or blank
  208.         mov    al, ch
  209.         cbw                ; AX = hour
  210.         call    IntToAsc        ; Convert to ASCII chars
  211.         mov    time.wHour, ax        ;   and place in structure
  212.         mov    al, cl
  213.         cbw                ; AX = minute
  214.         call    IntToAsc        ; Convert to ASCII chars
  215.         mov    time.wMin, ax        ;   and place in structure
  216.         pop    ax            ; AH = seconds
  217.         mov    al, ah
  218.         cbw                ; AX = seconds
  219.         call    IntToAsc        ; Convert to ASCII chars
  220.         mov    time.wSec, ax        ;   and place in structure
  221.  
  222.         mov    dx, ds            ; Return far ptr to time
  223.         mov    ax, OFFSET time        ;   string in DX:AX
  224.         Epilog                ; Epilogue macro
  225.         ret
  226.  
  227. GetSysTime    ENDP
  228.  
  229.  
  230.  
  231. ;* GetSysDate
  232. ;*
  233. ;* Creates qualified date in English, French, Spanish, German, Italian, 
  234. ;* or Swedish.  For the sake of simplicity, English is assumed for other 
  235. ;* countries, though the code can be easily extended to include other 
  236. ;* languages.
  237. ;*
  238. ;* Entry:    none
  239. ;* Return:    DX:AX = far pointer to ASCIIZ date string
  240.  
  241. GetSysDate    PROC    FAR EXPORT USES si di
  242.  
  243.         Prolog                ; Prologue macro
  244.         mov    ah, 2Ah            ; DOS service 2Ah
  245.         call    DOS3Call        ; Get System Date
  246.         push    cx            ; Save year
  247.         push    ds
  248.         pop    es            ; ES = DS
  249.         mov    bx, indx        ; BX = language index
  250.         mov    di, days[bx]        ; ES:DI points to array
  251.         cbw                ;    of ASCIIZ strings
  252.         xchg    ah, al            ; AH = day of week (0-7)
  253.                         ; AL = 0
  254.         .WHILE    ( ah )            ; Count AH strings to find
  255.         mov    cl, 255            ;   current day
  256.     repne    scasb                ; Scan for end of string
  257.         dec    ah            ; Decrement counter
  258.         .ENDW
  259.  
  260.         mov    si, di            ; DS:SI points to day string
  261.         mov    di, OFFSET Date        ; ES:DI points to buffer
  262.         .REPEAT
  263.         lodsb                ; Copy ASCIIZ day to
  264.         stosb                ;   buffer until null
  265.         .UNTIL    ( !al )            ;   terminator
  266.  
  267.         dec    di            ; ES:DI points to end of day
  268.         mov    ax, ' ,'        ; Follow day with ', '
  269.         stosw
  270.         mov    si, di            ; Save current buffer position
  271.         mov    di, months[bx]        ; ES:DI points to array
  272.         sub    al, al            ;   of ASCIIZ strings
  273.         dec    dh            ; DH = number of month:
  274.  
  275.         .WHILE    ( dh )            ;   0=Jan, 1=Feb, etc.
  276.         mov    cl, 255
  277.     repne    scasb                ; Scan for end of string
  278.         dec    dh            ; Decrement counter
  279.         .ENDW
  280.  
  281.         xchg    si, di            ; DS:SI points to month string
  282.         .REPEAT                ; ES:DI points to buffer
  283.         lodsb                ; Copy ASCIIZ month to
  284.         stosb                ;   buffer until null
  285.         .UNTIL    ( !al )            ;   terminator
  286.  
  287.         mov    BYTE PTR [di-1], ' '    ; Follow month with space
  288.         mov    al, dl
  289.         cbw                ; AX = day of month
  290.         call    IntToAsc        ; Convert to ASCII
  291.         stosw                ; Copy after month
  292.         mov    ax, ' ,'        ;   and follow it with
  293.         stosw                ;   comma
  294.         pop    ax            ; AX = year (1980 to 2099)
  295.         call    IntToAsc        ; Convert to ASCII
  296.         xchg    dx, ax            ; AX = 1st two digits ('19')
  297.         stosw                ; Write to string
  298.         xchg    dx, ax            ; AX = last two digits
  299.         stosw                ; Write to string
  300.         sub    al, al            ; Terminate string with null
  301.         stosb                ;   to make ASCIIZ
  302.  
  303.         mov    dx, ds            ; Return far ptr to Date
  304.         mov    ax, OFFSET Date        ;   string in DX:AX
  305.         Epilog                ; Epilogue macro
  306.         ret
  307.  
  308. GetSysDate    ENDP
  309.  
  310.  
  311.  
  312. ;* GetSysInfo
  313. ;*
  314. ;* Place the following system information in structure type SysInfo:
  315. ;*
  316. ;*    * Windows version
  317. ;*    * DOS version
  318. ;*    * keyboard status (see Help, Interrupt 16h, for keyboard flags)
  319. ;*    * number of floppy disk drives
  320. ;*    * math coprocessor installed?
  321. ;*    * video mode
  322. ;*    * processor type:    0 = 8086/88
  323. ;*                1 = 80186
  324. ;*                2 = 80286
  325. ;*                3 = 80386
  326. ;*                4 = 80486
  327. ;*    * ROM release date
  328. ;*
  329. ;* Entry:    none
  330. ;* Return:    DX:AX = far pointer to structure
  331.  
  332. GetSysInfo    PROC    FAR EXPORT
  333.  
  334.         Prolog                ; Prologue macro
  335.  
  336. ;
  337. ; Create ASCIIZ strings in structure with version numbers
  338. ; of Windows and DOS -- '03.10' and '05.00', for example
  339. ;
  340.         INVOKE    GetVersion
  341.         mov    bx, dx            ; Save DOS version
  342.         push    ax
  343.         cbw                ; AX = major Win version
  344.         call    IntToAsc        ; Make it ASCII
  345.         mov    WORD PTR sys.szWinVer, ax
  346.         pop    ax            ; Recover minor version
  347.         xchg    ah, al
  348.         cbw                ; AX = minor Win version
  349.         call    IntToAsc        ; Make it ASCII
  350.         mov    WORD PTR sys.szWinVer[3], ax
  351.         mov    ax, bx            ; Recover DOS version
  352.         xchg    ah, al
  353.         cbw                ; AX = major DOS version
  354.         call    IntToAsc        ; Make it ASCII
  355.         mov    WORD PTR sys.szDOSVer, ax
  356.         mov    ax, bx
  357.         cbw                ; AX = minor DOS version
  358.         call    IntToAsc        ; Make it ASCII
  359.         mov    WORD PTR sys.szDOSVer[3], ax
  360.  
  361. ;
  362. ; Read various information from BIOS data area at segment 40h
  363. ;
  364.         INVOKE    AllocSelector, ds    ; Get new selector
  365.         INVOKE    SetSelectorBase,    ; Set it to BIOS data
  366.             ax, DATA_BASE        ;   area at 40:0000
  367.         push    ax            ; Save selector
  368.         INVOKE    SetSelectorLimit,
  369.             ax, DATA_LIM        ; Set read limit 
  370.         pop    es            ; ES points to data
  371.         mov    al, es:[EQUIP]        ; Get equipment list
  372.         and    al, 10y            ; Mask bit 2
  373.         shr    al, 1            ; AL = TRUE if math
  374.         mov    sys.bCoproc, al        ;   coprocessor found
  375.         mov    al, es:[EQUIP]        ; Get list again
  376.         and    al, 11000000y        ; Mask bits 6-7
  377.         rol    al, 1            ; Rotate bits 6-7
  378.         rol    al, 1            ;   to bits 0-1
  379.         inc    ax            ; AL = number of    
  380.         mov    sys.cFloppy, al        ;   floppy disk drives
  381.         mov    ax, es:[KB]        ; AX = keyboard status
  382.         mov    sys.wKbStatus, ax    ; Keep it
  383.         mov    al, es:[VIDMODE]    ; AL = current vid mode
  384.         mov    sys.cVidMode, al    ; Keep it
  385.         INVOKE    FreeSelector, es    ; Free selector
  386.  
  387. ;
  388. ; Get processor type:  0=8086, 1=80186, 2=80286, etc.
  389. ;
  390.         INVOKE    GetWinFlags        ; AL = return flags
  391.         mov    ah, -1            ; Initialize processor type
  392.         mov    bx, -1            ; Initialize array index
  393.         mov    cx, LENGTHOF procs    ; CX = number of elements
  394.  
  395. @@:        inc    ah            ; Type = 0 for 8086, 1 for 186,
  396.         inc    bx            ;   2 for 286, etc
  397.         test    al, procs[bx]        ; Test return flags
  398.         loopz    @B            ; Loop until bits match
  399.         mov    sys.cProcType, ah    ; Store processor type
  400.  
  401. ;
  402. ; Read ROM release date from address FFFF:0005
  403. ;
  404.         INVOKE    AllocSelector, ds    ; Get new selector
  405.         INVOKE    SetSelectorBase,    ; Set it to start of
  406.             ax, ROM_BASE        ;   segment FFFF:0000
  407.         push    ds            ; Save local data segment addr
  408.         push    ax            ; Save new selector
  409.         INVOKE    SetSelectorLimit,
  410.             ax, ROM_LIM        ; Set read limit
  411.         push    ds
  412.         pop    es            ; Point ES:DI to hold buffer
  413.         mov    di, OFFSET sys.szROM    ;   (target) in structure
  414.         pop    ds            ; Point DS:SI to source
  415.         mov    si, DATE_OFF        ;   at FFFF:0005
  416.         mov    cx, LENGTHOF sys.szROM-1; CX = string length
  417.     rep    movsb                ; Copy release date to buffer
  418.         mov    ax, ds            ; DS will be invalid when freed,
  419.         pop    ds            ;    so restore orig DS now
  420.         INVOKE    FreeSelector, ax    ; Free allocated selector
  421.  
  422.         mov    dx, ds            ; Return far pointer
  423.         mov    ax, OFFSET sys        ;   to structure in DX:AX
  424.         Epilog                ; Epilogue macro
  425.         ret
  426.  
  427. GetSysInfo    ENDP
  428.  
  429.  
  430.  
  431. ;* Place WEP procedure in its own code segment, set as PRELOAD FIXED
  432. ;* in the SYSINFO.DEF module-definition file
  433. ;*
  434. CODE2    SEGMENT WORD 'CODE'
  435.     ASSUME    cs:CODE2
  436.  
  437. ;* WEP
  438. ;*
  439. ;* Windows Exit Procedure called by Windows before unloading.
  440. ;* 
  441. ;* Entry:    wExitCode = 0 if unloading SYSINFO
  442. ;*              = 1 if Windows shutting down
  443. ;* Return:    AX      = 1 to signal okay
  444.  
  445. WEP        PROC    FAR EXPORT
  446.  
  447.         Prolog
  448.         mov    ax, TRUE        ; Return AX = 1
  449.         Epilog
  450.         ret
  451.  
  452. WEP        ENDP
  453.  
  454. CODE2    ENDS
  455.  
  456. END
  457.