home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / VISUAL_B / FERRAMEN / KEEP_INI / INIFILE.BAS
Encoding:
BASIC Source File  |  1994-07-06  |  30.8 KB  |  1,076 lines

  1. '***************************************************************************
  2. '** INIFILE.BAS ** Third Public Release
  3. '*************************************************
  4. '** VB Module for simplifying .INI file operations
  5. '***************************************************************************
  6. 'Written and modified by Karl E. Peterson, February 1994, CIS 72302,3707.
  7. 'Portions originally downloaded from CompuServe's MSBASIC forum as
  8. 'MINIFILE.BAS, author unknown.  Comments and questions welcome!
  9. '***************************************************************************
  10. 'This module contains "wrappers" for just about anything you'd want to do
  11. 'with INI files.  The only prerequisite for using them is to register the
  12. 'particular INI path/filename and [Section] in advance of calling them.
  13. 'Register Private.Ini by calling PrivIniRegister, and Win.Ini by calling
  14. 'WinIniRegister.
  15. '
  16. 'This provides *safe* assured access to both application (Private.Ini) and
  17. 'Windows (Win.Ini) initialization files, with no need to worry about proper
  18. 'declarations and calling conventions.  It also greatly simplifies the task
  19. 'of repeatedly reading or writing to an Ini file.
  20. '
  21. 'You are free to use this module as you see fit.  If you like it, I'd really
  22. 'appreciate hearing that!  If you don't like it, or have problems with it,
  23. 'I'd like to know that too.
  24. '***************************************************************************
  25. 'The SECOND RELEASE added a dozen new functions, and two old ones were renamed.
  26. 'Latest modifications, June 1994
  27. '  WinGetSectionEntries() is now WinGetSectEntries()
  28. '  PrivGetSectionEntries() is now PrivGetSectEntries()
  29. 'Two new functions retrieve an entire [Section], entries and values, into an
  30. 'array from either Win.Ini or Private.Ini.  These functions are:
  31. '  WinGetSectEntriesEx()
  32. '  PrivGetSectEntriesEx()
  33. 'The other four deal with problems associated with multiple "device=" lines
  34. 'in System.Ini.  Use these at your *own risk*!  Especially the ones that add
  35. 'or remove a device.  These functions are:
  36. '  SysDevAdd()              Adds a "device=" line to System.Ini
  37. '  SysDevRemove()           Removes a "device=" line from System.Ini
  38. '  SysDevLoaded()           Checks for a specific "device=" line
  39. '  SysDevGetList()          Retrieves array of all devices
  40. 'The last six deal with [Section]'s.
  41. '  Win/PrivGetSections()    Retrieves list of all [Section]'s
  42. '  Win/PrivGetSectionsEx()  Retrieves array of all [Section]'s
  43. '  Win/PrivSectionExist()   Verifies existence of registered [Section]
  44. '***************************************************************************
  45. 'This THIRD RELEASE fixes a problem with the SysDevLoaded and SysDevRemove
  46. 'functions.  Neither worked if comments were on the same line.  Also, a flag
  47. 'has been added so that paths can be ignored or enforced with the SysXXX
  48. 'functions.  All API calls have been Aliased, so that this module may more
  49. 'easily be incorporated into existing programs.  Four new routines have
  50. 'been added:
  51. '  SysIniRegister()         Set nmSysPath flag
  52. '  ExtractName$()           Returns filename from filespec
  53. '  ExtractPath$()           Returns path from filespec
  54. '  StripComment$()          Removes trailing comments/spaces
  55. '***************************************************************************
  56.  
  57. Option Explicit
  58.  
  59. '** Windows API calls
  60. '(NOTE: Profile calls *altered* from those found in WIN30API.TXT!)
  61.   Declare Function kpGetProfileInt Lib "Kernel" Alias "GetProfileInt" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal nDefault As Integer) As Integer
  62.   Declare Function kpGetProfileString Lib "Kernel" Alias "GetProfileString" (ByVal lpAppName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer) As Integer
  63.   Declare Function kpWriteProfileString Lib "Kernel" Alias "WriteProfileString" (ByVal lpAppName As Any, ByVal lpKeyName As Any, ByVal lpString As Any) As Integer
  64.   Declare Function kpGetPrivateProfileInt Lib "Kernel" Alias "GetPrivateProfileInt" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal nDefault As Integer, ByVal lpFileName As String) As Integer
  65.   Declare Function kpGetPrivateProfileString Lib "Kernel" Alias "GetPrivateProfileString" (ByVal lpAppName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer
  66.   Declare Function kpWritePrivateProfileString Lib "Kernel" Alias "WritePrivateProfileString" (ByVal lpAppName As Any, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Integer
  67.   Declare Function kpSendMessage Lib "User" Alias "SendMessage" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long
  68.   Declare Function kpGetWindowsDirectory Lib "Kernel" Alias "GetWindowsDirectory" (ByVal lpBuffer As String, ByVal nSize As Integer) As Integer
  69.  
  70. '** Module-level variables for [Section] and Ini file names
  71.   Dim smSectionName As String   'Current section in private Ini file
  72.   Dim smIniFileName As String   'Fully qualified path/name of current private Ini file
  73.   Dim smWinSection As String    'Current section in Win.Ini
  74.   Dim nmWinInit As Integer      'Flag to indicate that Win.Ini section is initialized
  75.   Dim nmPrivInit As Integer     'Flag to indicate that Private.Ini is initialized
  76.   Dim nmSysPath As Integer      'Flag to indicate whether paths should be used with DEVICE=
  77.  
  78. '** Constants used to size buffers
  79.   Const Max_SectionBuffer = 4096
  80.   Const Max_EntryBuffer = 255
  81.  
  82. '** Special values to alert other apps of Win.Ini changes
  83.   Const HWND_BROADCAST = &HFFFF
  84.   Const WM_WININICHANGE = &H1A
  85.  
  86. Function ExtractName$ (sSpecIn$, nBaseOnly%)
  87.   
  88.   Dim nCnt%, nDot%, sSpecOut$
  89.  
  90.   On Local Error Resume Next
  91.  
  92.   If InStr(sSpecIn, "\") Then
  93.     For nCnt = Len(sSpecIn) To 1 Step -1
  94.       If Mid$(sSpecIn, nCnt, 1) = "\" Then
  95.         sSpecOut = Mid$(sSpecIn, nCnt + 1)
  96.         Exit For
  97.       End If
  98.     Next nCnt
  99.   
  100.   ElseIf InStr(sSpecIn, ":") = 2 Then
  101.     sSpecOut = Mid$(sSpecIn, 3)
  102.     
  103.   Else
  104.     sSpecOut = sSpecIn
  105.   End If
  106.     
  107.   If nBaseOnly Then
  108.     nDot = InStr(sSpecOut, ".")
  109.     If nDot Then
  110.       sSpecOut = Left$(sSpecOut, nDot - 1)
  111.     End If
  112.   End If
  113.  
  114.   ExtractName$ = UCase$(sSpecOut)
  115.  
  116. End Function
  117.  
  118. Function ExtractPath$ (sSpecIn$)
  119.  
  120.   Dim nCnt%, sSpecOut$
  121.   
  122.   On Local Error Resume Next
  123.  
  124.   If InStr(sSpecIn, "\") Then
  125.     For nCnt = Len(sSpecIn) To 1 Step -1
  126.       If Mid$(sSpecIn, nCnt, 1) = "\" Then
  127.         sSpecOut = Left$(sSpecIn, nCnt)
  128.         Exit For
  129.       End If
  130.     Next nCnt
  131.   
  132.   ElseIf InStr(sSpecIn, ":") = 2 Then
  133.     sSpecOut = CurDir$(sSpecIn)
  134.     If Len(sSpecOut) = 0 Then sSpecOut = CurDir$
  135.  
  136.   Else
  137.     sSpecOut = CurDir$
  138.   End If
  139.     
  140.   If Right$(sSpecOut, 1) <> "\" Then
  141.     sSpecOut = sSpecOut + "\"
  142.   End If
  143.   ExtractPath$ = UCase$(sSpecOut)
  144.  
  145. End Function
  146.  
  147. Sub Main ()
  148.   'This subroutine is useful for simply testing the other routines in this
  149.   'module.  Make this module the only one in a project, and set Sub Main as
  150.   'the entry point.  Then enter the code you wish to test below.
  151. End Sub
  152.  
  153. Sub PrivClearEntry (sEntryName As String)
  154.  
  155.   'Bail if not initialized
  156.     If Not nmPrivInit Then
  157.       PrivIniNotReg
  158.       Exit Sub
  159.     End If
  160.  
  161.   'Sets a specific entry in Private.Ini to Nothing or Blank
  162.     Dim nRetVal As Integer
  163.     nRetVal = kpWritePrivateProfileString(smSectionName, sEntryName, "", smIniFileName)
  164.  
  165. End Sub
  166.  
  167. Sub PrivDeleteEntry (sEntryName As String)
  168.  
  169.   'Bail if not initialized
  170.     If Not nmPrivInit Then
  171.       PrivIniNotReg
  172.       Exit Sub
  173.     End If
  174.  
  175.   'Deletes a specific entry in Private.Ini
  176.     Dim nRetVal As Integer
  177.     nRetVal = kpWritePrivateProfileString(smSectionName, sEntryName, 0&, smIniFileName)
  178.  
  179. End Sub
  180.  
  181. Sub PrivDeleteSection ()
  182.  
  183.   'Bail if not initialized
  184.     If Not nmPrivInit Then
  185.       PrivIniNotReg
  186.       Exit Sub
  187.     End If
  188.  
  189.   'Deletes an *entire* [Section] and all its Entries in Private.Ini
  190.     Dim nRetVal As Integer
  191.     nRetVal = kpWritePrivateProfileString(smSectionName, 0&, 0&, smIniFileName)
  192.  
  193.   'Now Private.Ini needs to be reinitialized
  194.     smSectionName = ""
  195.     nmPrivInit = False
  196.  
  197. End Sub
  198.  
  199. Function PrivGetInt (sEntryName As String, nDefaultValue As Integer) As Integer
  200.  
  201.   'Bail if not initialized
  202.     If Not nmPrivInit Then
  203.       PrivIniNotReg
  204.       Exit Function
  205.     End If
  206.  
  207.   'Retrieves an Integer value from Private.Ini, range: 0-32767
  208.     PrivGetInt = kpGetPrivateProfileInt(smSectionName, sEntryName, nDefaultValue, smIniFileName)
  209.  
  210. End Function
  211.  
  212. Function PrivGetSectEntries () As String
  213.  
  214.   'Bail if not initialized
  215.     If Not nmPrivInit Then
  216.       PrivIniNotReg
  217.       Exit Function
  218.     End If
  219.  
  220.   'Retrieves all Entries in a [Section] of Private.Ini
  221.   'Entries nul terminated; last entry double-terminated
  222.     Dim sTemp As String * Max_SectionBuffer
  223.     Dim nRetVal As Integer
  224.     nRetVal = kpGetPrivateProfileString(smSectionName, 0&, "", sTemp, Len(sTemp), smIniFileName)
  225.     PrivGetSectEntries$ = Left$(sTemp, nRetVal + 1)
  226.  
  227. End Function
  228.  
  229. Function PrivGetSectEntriesEx (sTable() As String) As Integer
  230.  
  231.   'Bail if not initialized
  232.     If Not nmPrivInit Then
  233.       PrivIniNotReg
  234.       Exit Function
  235.     End If
  236.  
  237.   'Example of usage, note return is one higher than UBound
  238.     'Dim i%, n%
  239.     'Dim eTable() As String
  240.     'PrivIniRegister "386Enh", "System.Ini"
  241.     'n% = PrivGetSectionEntriesEx(eTable())
  242.     'For i = 0 To n - 1
  243.     '  Debug.Print eTable(0, i); "="; eTable(1, i)
  244.     'Next i
  245.  
  246.   'Retrieves all Entries in a [Section] of Private.Ini
  247.   'Entries nul terminated; last entry double-terminated
  248.     Dim sBuff As String * Max_SectionBuffer
  249.     Dim sTemp As String
  250.     Dim nRetVal As Integer
  251.     nRetVal = kpGetPrivateProfileString(smSectionName, 0&, "", sBuff, Len(sBuff), smIniFileName)
  252.     sTemp = Left$(sBuff, nRetVal + 1)
  253.  
  254.   'Parse entries into first dimension of table
  255.   'and retrieve values into second dimension
  256.     Dim nEntries As Integer
  257.     Dim nNull As Integer
  258.     Do While Asc(sTemp)
  259.       ReDim Preserve sTable(0 To 1, 0 To nEntries)
  260.       nNull = InStr(sTemp, Chr$(0))
  261.       sTable(0, nEntries) = Left$(sTemp, nNull - 1)
  262.       sTable(1, nEntries) = PrivGetString(sTable(0, nEntries), "")
  263.       sTemp = Mid$(sTemp, nNull + 1)
  264.       nEntries = nEntries + 1
  265.     Loop
  266.  
  267.   'Make function assignment
  268.     PrivGetSectEntriesEx = nEntries
  269.  
  270. End Function
  271.  
  272. Function PrivGetSections$ ()
  273.  
  274.   'Bail if not initialized
  275.     If Not nmPrivInit Then
  276.       PrivIniNotReg
  277.       Exit Function
  278.     End If
  279.  
  280.   'Setup some variables
  281.     Dim sRet As String
  282.     Dim sBuff As String
  283.     Dim hFile As Integer
  284.  
  285.   'Extract all [Section] lines
  286.     hFile = FreeFile
  287.     Open smIniFileName For Input As hFile
  288.     Do While Not EOF(hFile)
  289.       Line Input #hFile, sBuff
  290.       sBuff = StripComment$(sBuff)
  291.       If InStr(sBuff, "[") = 1 And InStr(sBuff, "]") = Len(sBuff) Then
  292.         sRet = sRet + Mid$(sBuff, 2, Len(sBuff) - 2) + Chr$(0)
  293.       End If
  294.     Loop
  295.     Close hFile
  296.  
  297.   'Assign return value
  298.     If Len(sRet) Then
  299.       PrivGetSections = sRet + Chr$(0)
  300.     Else
  301.       PrivGetSections = String$(2, 0)
  302.     End If
  303.  
  304. End Function
  305.  
  306. Function PrivGetSectionsEx (sTable() As String) As Integer
  307.  
  308.   'Get "normal" list of all [Section]'s
  309.     Dim sSect As String
  310.     sSect = PrivGetSections$()
  311.     If Len(sSect) = 0 Then
  312.       PrivGetSectionsEx = 0
  313.       Exit Function
  314.     End If
  315.  
  316.   'Parse [Section]'s into table
  317.     Dim nEntries As Integer
  318.     Dim nNull As Integer
  319.     Do While Asc(sSect)
  320.       ReDim Preserve sTable(0 To nEntries)
  321.       nNull = InStr(sSect, Chr$(0))
  322.       sTable(nEntries) = Left$(sSect, nNull - 1)
  323.       sSect = Mid$(sSect, nNull + 1)
  324.       nEntries = nEntries + 1
  325.     Loop
  326.  
  327.   'Make function assignment
  328.     PrivGetSectionsEx = nEntries
  329.   
  330. End Function
  331.  
  332. Function PrivGetString (sEntryName As String, ByVal sDefaultValue As String) As String
  333.  
  334.   'Bail if not initialized
  335.     If Not nmPrivInit Then
  336.       PrivIniNotReg
  337.       Exit Function
  338.     End If
  339.  
  340.   'Retrieves Specific Entry from Private.Ini
  341.     Dim sTemp As String * Max_EntryBuffer
  342.     Dim nRetVal As Integer
  343.     nRetVal = kpGetPrivateProfileString(smSectionName, sEntryName, sDefaultValue, sTemp, Len(sTemp), smIniFileName)
  344.     If nRetVal Then
  345.       PrivGetString = Left$(sTemp, nRetVal)
  346.     End If
  347.  
  348. End Function
  349.  
  350. Function PrivGetTF (sEntryName As String, nDefaultValue As Integer)
  351.   
  352.   'Retrieves Specific Entry as either True/False from Private.Ini
  353.   'local vars
  354.     Dim sTF As String
  355.     Dim sDefault As String
  356.  
  357.   'get string value from INI
  358.     If nDefaultValue Then
  359.       sDefault = "true"
  360.     Else
  361.       sDefault = "false"
  362.     End If
  363.     sTF = PrivGetString(sEntryName, sDefault)
  364.  
  365.   'interpret return string
  366.     Select Case Trim$(UCase$(sTF))
  367.       Case "YES", "Y", "TRUE", "T", "ON", "1", "-1"
  368.         PrivGetTF = True
  369.       Case "NO", "N", "FALSE", "F", "OFF", "0"
  370.         PrivGetTF = False
  371.       Case Else
  372.         PrivGetTF = False
  373.     End Select
  374.  
  375. End Function
  376.  
  377. Sub PrivIniFlushCache ()
  378.  
  379.   'Bail if not initialized
  380.     If Not nmPrivInit Then
  381.       PrivIniNotReg
  382.       Exit Sub
  383.     End If
  384.  
  385.   'To improve performance, Windows keeps a cached version of the most-recently
  386.   'accessed initialization file. If that filename is specified and the other
  387.   'three parameters are NULL, Windows flushes the cache
  388.     Dim nRetVal As Integer
  389.     nRetVal = kpWritePrivateProfileString(0&, 0&, 0&, smIniFileName)
  390.  
  391. End Sub
  392.  
  393. Private Sub PrivIniNotReg ()
  394.   
  395.   'Warn *PROGRAMMER* that there's a logic error!
  396.     MsgBox "[Section] and FileName Not Registered in Private.Ini!", 16, "IniFile Logic Error"
  397.  
  398. End Sub
  399.  
  400. Sub PrivIniRead (SectionName$, KeyName$, nDefault%, ByVal DefaultStr$, ReturnStr$, Numeric%, IniFileName$)
  401.  
  402.   'One-shot read from Private.Ini, more *work* than it's worth
  403.     Dim nRetVal As Integer
  404.     Dim RetStr As String * Max_EntryBuffer 'Create an empty string to be filled
  405.  
  406.     If Numeric% Then    'we are looking for integer input
  407.       Numeric% = kpGetPrivateProfileInt(SectionName$, KeyName$, nDefault%, IniFileName$)
  408.     Else
  409.       nRetVal = kpGetPrivateProfileString(SectionName$, KeyName$, DefaultStr$, RetStr$, Len(RetStr$), IniFileName$)
  410.       If nRetVal Then
  411.         ReturnStr$ = Left$(RetStr$, nRetVal)
  412.       End If
  413.     End If
  414.  
  415. End Sub
  416.  
  417. Sub PrivIniRegister (sSectionName As String, sIniFileName As String)
  418.  
  419.   'Store module-level values for future reference
  420.     smSectionName = Trim$(sSectionName)
  421.     smIniFileName = Trim$(sIniFileName)
  422.     nmPrivInit = True
  423.  
  424. End Sub
  425.  
  426. Sub PrivIniWrite (SectionName$, IniFileName$, EntryName$, ByVal NewVal$)
  427.     
  428.   'One-shot write to Private.Ini, more *work* than it's worth
  429.     Dim nRetVal As Integer
  430.     nRetVal = kpWritePrivateProfileString(SectionName$, EntryName$, NewVal$, IniFileName$)
  431.     
  432. End Sub
  433.  
  434. Function PrivPutInt (sEntryName As String, nValue As Integer) As Integer
  435.  
  436.   'Bail if not initialized
  437.     If Not nmPrivInit Then
  438.       PrivIniNotReg
  439.       Exit Function
  440.     End If
  441.  
  442.   'Write an integer to Private.Ini
  443.     PrivPutInt = kpWritePrivateProfileString(smSectionName, sEntryName, Format$(nValue), smIniFileName)
  444.  
  445. End Function
  446.  
  447. Function PrivPutString (sEntryName As String, ByVal sValue As String) As Integer
  448.  
  449.   'Bail if not initialized
  450.     If Not nmPrivInit Then
  451.       PrivIniNotReg
  452.       Exit Function
  453.     End If
  454.  
  455.   'Write a string to Private.Ini
  456.     PrivPutString = kpWritePrivateProfileString(smSectionName, sEntryName, sValue, smIniFileName)
  457.  
  458. End Function
  459.  
  460. Function PrivPutTF (sEntryName As String, nValue As Integer)
  461.  
  462.   'Set an entry in Private.Ini to True/False
  463.   'local vars
  464.     Dim sTF As String
  465.  
  466.   'create INI string
  467.     If nValue Then
  468.       sTF = "true"
  469.     Else
  470.       sTF = "false"
  471.     End If
  472.  
  473.   'write new value
  474.     PrivPutTF = PrivPutString(sEntryName, sTF)
  475.  
  476. End Function
  477.  
  478. Function PrivSectExist () As Integer
  479.  
  480.   'Retrieve list of all [Section]'s
  481.     Dim sSect As String
  482.     sSect = PrivGetSections$()
  483.     If Len(sSect) = 0 Then
  484.       PrivSectExist = False
  485.       Exit Function
  486.     End If
  487.  
  488.   'Check for existence registered [Section]
  489.     sSect = Chr$(0) + UCase$(sSect)
  490.     If InStr(sSect, Chr$(0) + UCase$(smSectionName) + Chr$(0)) Then
  491.       PrivSectExist = True
  492.     Else
  493.       PrivSectExist = False
  494.     End If
  495.  
  496. End Function
  497.  
  498. Private Function StripComment$ (ByVal StrIn$)
  499.   Dim nRet%
  500.   'Check for comment
  501.     nRet = InStr(StrIn, ";")
  502.  
  503.   'Remove it if present
  504.     If nRet = 1 Then
  505.       'Whole string is a comment
  506.         StripComment = ""
  507.         Exit Function
  508.     ElseIf nRet > 1 Then
  509.       'Strip comment
  510.         StrIn = Left$(StrIn, nRet - 1)
  511.     End If
  512.   
  513.   'Trim any trailing space
  514.     StripComment = Trim$(StrIn)
  515.  
  516. End Function
  517.  
  518. Function SysDevAdd (sNewDev$, sComment$, sBAK$) As Integer
  519.   
  520.   'Setup some variables
  521.     Dim sSysIni As String
  522.     Dim sSysBak As String
  523.     Dim sBuff() As String
  524.     Dim sTemp As String
  525.     Dim nRet As Integer
  526.     Dim hFile As Integer
  527.     Dim nCnt As Integer
  528.     Dim fAdded As Integer
  529.  
  530.   'Find System.Ini, and make backup
  531.     sTemp = String$(Max_EntryBuffer, 0)
  532.     nRet = kpGetWindowsDirectory(sTemp, Max_EntryBuffer)
  533.     sSysIni = Left$(sTemp, nRet) + "\System.Ini"
  534.     If Len(Trim$(sBAK)) Then
  535.       sSysBak = Left$(sTemp, nRet) + "\System." + sBAK
  536.       On Local Error Resume Next
  537.         FileCopy sSysIni, sSysBak
  538.         If Err Then
  539.           SysDevAdd = False
  540.           Exit Function
  541.         End If
  542.       On Local Error GoTo 0
  543.     End If
  544.  
  545.   'Read entire file, and insert new line
  546.     hFile = FreeFile
  547.     Open sSysIni For Input As hFile
  548.     Do While Not EOF(hFile)
  549.       nCnt = nCnt + 1
  550.       ReDim Preserve sBuff(1 To nCnt)
  551.       Line Input #hFile, sBuff(nCnt)
  552.       If Not fAdded Then
  553.         sTemp = UCase$(Trim$(sBuff(nCnt)))
  554.         If sTemp = "[386ENH]" Then
  555.           sTemp = Trim$(sNewDev)
  556.           sComment = Trim$(sComment)
  557.           If Len(sComment) Then
  558.             sTemp = sTemp + "    ;" + sComment
  559.           End If
  560.           nCnt = nCnt + 1
  561.           ReDim Preserve sBuff(1 To nCnt)
  562.           sBuff(nCnt) = "device=" + sTemp
  563.           fAdded = True
  564.         End If
  565.       End If
  566.     Loop
  567.     Close hFile
  568.  
  569.   'Write file back out
  570.     hFile = FreeFile
  571.     Open sSysIni For Output As hFile
  572.     For nCnt = LBound(sBuff) To UBound(sBuff)
  573.       Print #hFile, sBuff(nCnt)
  574.     Next nCnt
  575.     Close hFile
  576.  
  577.   'Make sure all went well
  578.     SysDevAdd = SysDevLoaded(sNewDev)
  579.  
  580. End Function
  581.  
  582. Function SysDevGetList (sTable() As String) As Integer
  583.   
  584.   'Setup some variables
  585.     Dim sSysIni As String
  586.     Dim sBuff As String
  587.     Dim nRet As Integer
  588.     Dim hFile As Integer
  589.     Dim nCnt As Integer
  590.  
  591.   'Example of usage, note return is one higher than UBound
  592.   'Returned values *always* have paths, if present
  593.     'Dim i%, n%
  594.     'Dim eTable() As String
  595.     'n% = SysDevGetList(eTable())
  596.     'For i = 0 To n - 1
  597.     '  Debug.Print "device="; eTable(i)
  598.     'Next i
  599.   
  600.   'Find System.Ini
  601.     sBuff = String$(Max_EntryBuffer, 0)
  602.     nRet = kpGetWindowsDirectory(sBuff, Max_EntryBuffer)
  603.     sSysIni = Left$(sBuff, nRet) + "\System.Ini"
  604.  
  605.   'Extract all device lines
  606.     hFile = FreeFile
  607.     Open sSysIni For Input As hFile
  608.     Do While Not EOF(hFile)
  609.       Line Input #hFile, sBuff
  610.       sBuff = UCase$(Trim$(sBuff))
  611.       If InStr(sBuff, "DEVICE=") = 1 Then
  612.         ReDim Preserve sTable(0 To nCnt)
  613.         sTable(nCnt) = StripComment$(Mid$(sBuff, 8))
  614.         nCnt = nCnt + 1
  615.       End If
  616.     Loop
  617.     Close hFile
  618.  
  619.   'Make final assignment
  620.     SysDevGetList = nCnt
  621.  
  622. End Function
  623.  
  624. Function SysDevLoaded (sDevChk As String) As Integer
  625.  
  626.   'Set up some variables
  627.     Dim nCnt As Integer
  628.     Dim nLoop As Integer
  629.     Dim dTable() As String
  630.     Dim sTemp As String
  631.     
  632.   'Example of usage
  633.     'SysIniRegister True   'Enforce path checking
  634.     'If SysDevLoaded("VShare.386") Then
  635.     '  MsgBox "VShare.386 *IS* Loaded!"
  636.     'Else
  637.     '  MsgBox "VShare.386 *NOT* Loaded!"
  638.     'End If
  639.   
  640.   'Get list of all devices loaded
  641.     nCnt = SysDevGetList(dTable())
  642.  
  643.   'Check for specific one
  644.     For nLoop = 0 To nCnt - 1
  645.       If nmSysPath Then
  646.         sTemp = dTable(nLoop)
  647.       Else
  648.         sTemp = ExtractName$(dTable(nLoop), False)
  649.       End If
  650.       If sTemp = UCase$(sDevChk) Then
  651.         SysDevLoaded = True
  652.         Exit For
  653.       End If
  654.     Next nLoop
  655.  
  656. End Function
  657.  
  658. Function SysDevRemove (sOldDev$, sBAK$) As Integer
  659.   
  660.   'Setup some variables
  661.     Dim sSysIni As String
  662.     Dim sSysBak As String
  663.     Dim sBuff() As String
  664.     Dim sTemp As String
  665.     Dim nTempFlag As Integer
  666.     Dim nRet As Integer
  667.     Dim hFile As Integer
  668.     Dim nCnt As Integer
  669.     Dim fRemoved As Integer
  670.  
  671.   'Make sure it's there (somewhere)!
  672.     nTempFlag = nmSysPath  'Store and temp set path flag
  673.     SysIniRegister False
  674.       nRet = SysDevLoaded(sOldDev)
  675.     SysIniRegister nTempFlag
  676.     If Not nRet Then       'Definately not there
  677.       SysDevRemove = True
  678.       Exit Function
  679.     End If
  680.   
  681.   'Find System.Ini, and make backup
  682.     sTemp = String$(Max_EntryBuffer, 0)
  683.     nRet = kpGetWindowsDirectory(sTemp, Max_EntryBuffer)
  684.     sSysIni = Left$(sTemp, nRet) + "\System.Ini"
  685.     If Len(Trim$(sBAK)) Then
  686.       sSysBak = Left$(sTemp, nRet) + "\System." + sBAK
  687.       On Local Error Resume Next
  688.         FileCopy sSysIni, sSysBak
  689.         If Err Then
  690.           SysDevRemove = False
  691.           Exit Function
  692.         End If
  693.       On Local Error GoTo 0
  694.     End If
  695.  
  696.   'Read entire file, and remove old device line
  697.     hFile = FreeFile
  698.     Open sSysIni For Input As hFile
  699.     Do While Not EOF(hFile)
  700.       nCnt = nCnt + 1
  701.       ReDim Preserve sBuff(1 To nCnt)
  702.       Line Input #hFile, sBuff(nCnt)
  703.       If Not fRemoved Then
  704.         sTemp = UCase$(Trim$(sBuff(nCnt)))
  705.         If InStr(sTemp, "DEVICE=") = 1 Then
  706.           'Get what follows & strip comments
  707.           sTemp = StripComment$(Mid$(sTemp, 8))
  708.           If Not nmSysPath Then 'Ignore path
  709.             sTemp = ExtractName$(sTemp, False)
  710.           End If
  711.           If sTemp = UCase(sOldDev) Then
  712.             nCnt = nCnt - 1
  713.             ReDim Preserve sBuff(1 To nCnt)
  714.             fRemoved = True
  715.           End If
  716.         End If
  717.       End If
  718.     Loop
  719.     Close hFile
  720.  
  721.   'Write file back out
  722.     hFile = FreeFile
  723.     Open sSysIni For Output As hFile
  724.     For nCnt = LBound(sBuff) To UBound(sBuff)
  725.       Print #hFile, sBuff(nCnt)
  726.     Next nCnt
  727.     Close hFile
  728.  
  729.   'Make sure all went well
  730.     If fRemoved Then
  731.       nTempFlag = nmSysPath  'Store and temp set path flag
  732.       SysIniRegister False
  733.         nRet = SysDevLoaded(sOldDev)
  734.       SysIniRegister nTempFlag
  735.       SysDevRemove = Not nRet
  736.     End If
  737.  
  738. End Function
  739.  
  740. Sub SysIniRegister (nPathFlag%)
  741.  
  742.   'Store module-level flag for future reference
  743.     nmSysPath = nPathFlag
  744.  
  745. End Sub
  746.  
  747. Sub WinClearEntry (sEntryName As String)
  748.  
  749.   'Bail if not initialized
  750.     If Not nmWinInit Then
  751.       WinIniNotReg
  752.       Exit Sub
  753.     End If
  754.  
  755.   'Sets a specific entry in Win.Ini to Nothing or Blank
  756.     Dim nRetVal As Integer
  757.     nRetVal = kpWriteProfileString(smWinSection, sEntryName, "")
  758.     WinIniChanged
  759.  
  760. End Sub
  761.  
  762. Sub WinDeleteEntry (sEntryName As String)
  763.  
  764.   'Bail if not initialized
  765.     If Not nmWinInit Then
  766.       WinIniNotReg
  767.       Exit Sub
  768.     End If
  769.  
  770.   'Deletes a specific entry in Win.Ini
  771.     Dim nRetVal As Integer
  772.     nRetVal = kpWriteProfileString(smWinSection, sEntryName, 0&)
  773.     WinIniChanged
  774.  
  775. End Sub
  776.  
  777. Sub WinDeleteSection ()
  778.  
  779.   'Bail if not initialized
  780.     If Not nmWinInit Then
  781.       WinIniNotReg
  782.       Exit Sub
  783.     End If
  784.  
  785.   'Deletes an *entire* [Section] and all its Entries in Win.Ini
  786.     Dim nRetVal As Integer
  787.     nRetVal = kpWriteProfileString(smWinSection, 0&, 0&)
  788.   
  789.   'Now Win.Ini needs to be reinitialized
  790.     smWinSection = ""
  791.     nmWinInit = False
  792.     WinIniChanged
  793.  
  794. End Sub
  795.  
  796. Function WinGetInt (sEntryName As String, nDefaultValue As Integer) As Integer
  797.  
  798.   'Bail if not initialized
  799.     If Not nmWinInit Then
  800.       WinIniNotReg
  801.       Exit Function
  802.     End If
  803.  
  804.   'Retrieves an Integer value from Win.Ini, range: 0-32767
  805.     WinGetInt = kpGetProfileInt(smWinSection, sEntryName, nDefaultValue)
  806.  
  807. End Function
  808.  
  809. Function WinGetSectEntries () As String
  810.  
  811.   'Bail if not initialized
  812.     If Not nmWinInit Then
  813.       WinIniNotReg
  814.       Exit Function
  815.     End If
  816.  
  817.   'Retrieves all Entries in a [Section] of Win.Ini
  818.   'Entries nul terminated; last entry double-terminated
  819.     Dim sTemp As String * Max_SectionBuffer
  820.     Dim nRetVal As Integer
  821.     nRetVal = kpGetProfileString(smWinSection, 0&, "", sTemp, Len(sTemp))
  822.     WinGetSectEntries = Left$(sTemp, nRetVal + 1)
  823.  
  824. End Function
  825.  
  826. Function WinGetSectEntriesEx (sTable() As String) As Integer
  827.  
  828.   'Bail if not initialized
  829.     If Not nmWinInit Then
  830.       WinIniNotReg
  831.       Exit Function
  832.     End If
  833.  
  834.   'Example of usage, note return is one higher than UBound
  835.     'Dim i%, n%
  836.     'Dim eTable() As String
  837.     'WinIniRegister "Windows"
  838.     'n% = WinGetSectionEntriesEx(eTable())
  839.     'For i = 0 To n - 1
  840.     '  Debug.Print eTable(0, i); "="; eTable(1, i)
  841.     'Next i
  842.  
  843.   'Retrieves all Entries in a [Section] of Win.Ini
  844.   'Entries nul terminated; last entry double-terminated
  845.     Dim sBuff As String * Max_SectionBuffer
  846.     Dim sTemp As String
  847.     Dim nRetVal As Integer
  848.     nRetVal = kpGetProfileString(smWinSection, 0&, "", sBuff, Len(sBuff))
  849.     sTemp = Left$(sBuff, nRetVal + 1)
  850.  
  851.   'Parse entries into first dimension of table
  852.   'and retrieve values into second dimension
  853.     Dim nEntries As Integer
  854.     Dim nNull As Integer
  855.     Do While Asc(sTemp)
  856.       ReDim Preserve sTable(0 To 1, 0 To nEntries)
  857.       nNull = InStr(sTemp, Chr$(0))
  858.       sTable(0, nEntries) = Left$(sTemp, nNull - 1)
  859.       sTable(1, nEntries) = WinGetString(sTable(0, nEntries), "")
  860.       sTemp = Mid$(sTemp, nNull + 1)
  861.       nEntries = nEntries + 1
  862.     Loop
  863.  
  864.   'Make final assignment
  865.     WinGetSectEntriesEx = nEntries
  866.  
  867. End Function
  868.  
  869. Function WinGetSections$ ()
  870.  
  871.   'No real need to be initialized, Win.Ini *should* exist
  872.   
  873.   'Setup some variables
  874.     Dim sWinIni As String
  875.     Dim sRet As String
  876.     Dim sBuff As String
  877.     Dim hFile As Integer
  878.     Dim nRet As Integer
  879.   
  880.   'Find Win.Ini
  881.     sBuff = String$(Max_EntryBuffer, 0)
  882.     nRet = kpGetWindowsDirectory(sBuff, Max_EntryBuffer)
  883.     sWinIni = Left$(sBuff, nRet) + "\Win.Ini"
  884.  
  885.   'Extract all [Section] lines
  886.     hFile = FreeFile
  887.     Open sWinIni For Input As hFile
  888.     Do While Not EOF(hFile)
  889.       Line Input #hFile, sBuff
  890.       sBuff = StripComment$(sBuff)
  891.       If InStr(sBuff, "[") = 1 And InStr(sBuff, "]") = Len(sBuff) Then
  892.         sRet = sRet + Mid$(sBuff, 2, Len(sBuff) - 2) + Chr$(0)
  893.       End If
  894.     Loop
  895.     Close hFile
  896.  
  897.   'Assign return value
  898.     If Len(sRet) Then
  899.       WinGetSections = sRet + Chr$(0)
  900.     Else
  901.       WinGetSections = String$(2, 0)
  902.     End If
  903.  
  904. End Function
  905.  
  906. Function WinGetSectionsEx (sTable() As String) As Integer
  907.  
  908.   'Get "normal" list of all [Section]'s
  909.     Dim sSect As String
  910.     sSect = WinGetSections$()
  911.     If Len(sSect) = 0 Then
  912.       WinGetSectionsEx = 0
  913.       Exit Function
  914.     End If
  915.  
  916.   'Parse [Section]'s into table
  917.     Dim nEntries As Integer
  918.     Dim nNull As Integer
  919.     Do While Asc(sSect)
  920.       ReDim Preserve sTable(0 To nEntries)
  921.       nNull = InStr(sSect, Chr$(0))
  922.       sTable(nEntries) = Left$(sSect, nNull - 1)
  923.       sSect = Mid$(sSect, nNull + 1)
  924.       nEntries = nEntries + 1
  925.     Loop
  926.  
  927.   'Make function assignment
  928.     WinGetSectionsEx = nEntries
  929.   
  930. End Function
  931.  
  932. Function WinGetString (sEntryName As String, ByVal sDefaultValue As String) As String
  933.  
  934.   'Bail if not initialized
  935.     If Not nmWinInit Then
  936.       WinIniNotReg
  937.       Exit Function
  938.     End If
  939.  
  940.   'Retrieves Specific Entry from Win.Ini
  941.     Dim sTemp As String * Max_EntryBuffer
  942.     Dim nRetVal As Integer
  943.     nRetVal = kpGetProfileString(smWinSection, sEntryName, sDefaultValue, sTemp, Len(sTemp))
  944.     If nRetVal Then
  945.       WinGetString = Left$(sTemp, nRetVal)
  946.     End If
  947.  
  948. End Function
  949.  
  950. Function WinGetTF (sEntryName As String, nDefaultValue As Integer)
  951.   
  952.   'Retrieves Specific Entry as either True/False from Win.Ini
  953.   'local vars
  954.     Dim sTF As String
  955.     Dim sDefault As String
  956.  
  957.   'get string value from INI
  958.     If nDefaultValue Then
  959.       sDefault = "true"
  960.     Else
  961.       sDefault = "false"
  962.     End If
  963.     sTF = WinGetString(sEntryName, sDefault)
  964.  
  965.   'interpret return string
  966.     Select Case Trim$(UCase$(sTF))
  967.       Case "YES", "Y", "TRUE", "T", "ON", "1", "-1"
  968.         WinGetTF = True
  969.       Case "NO", "N", "FALSE", "F", "OFF", "0"
  970.         WinGetTF = False
  971.       Case Else
  972.         WinGetTF = False
  973.     End Select
  974.  
  975. End Function
  976.  
  977. Private Sub WinIniChanged ()
  978.   
  979.   'Notify all other applications that Win.Ini has been changed
  980.     Dim Rtn&
  981.     Rtn = kpSendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ByVal smWinSection)
  982.  
  983. End Sub
  984.  
  985. Sub WinIniFlushCache ()
  986.  
  987.   'Windows keeps a cached version of WIN.INI to improve performance.
  988.   'If all three parameters are NULL, Windows flushes the cache.
  989.     Dim nRetVal As Integer
  990.     nRetVal = kpWriteProfileString(0&, 0&, 0&)
  991.   
  992. End Sub
  993.  
  994. Private Sub WinIniNotReg ()
  995.  
  996.   'Warn *PROGRAMMER* that there's a logic error!
  997.     MsgBox "[Section] Not Registered in Win.Ini!", 16, "IniFile Logic Error"
  998.  
  999. End Sub
  1000.  
  1001. Sub WinIniRegister (sSectionName As String)
  1002.   
  1003.   'Store module-level for future reference
  1004.     smWinSection = Trim$(sSectionName)
  1005.     nmWinInit = True
  1006.  
  1007. End Sub
  1008.  
  1009. Function WinPutInt (sEntryName As String, nValue As Integer) As Integer
  1010.  
  1011.   'Bail if not initialized
  1012.     If Not nmWinInit Then
  1013.       WinIniNotReg
  1014.       Exit Function
  1015.     End If
  1016.  
  1017.   'Write an integer to Win.Ini
  1018.     WinPutInt = kpWriteProfileString(smWinSection, sEntryName, Format$(nValue))
  1019.     WinIniChanged
  1020.  
  1021. End Function
  1022.  
  1023. Function WinPutString (sEntryName As String, ByVal sValue As String) As Integer
  1024.  
  1025.   'Bail if not initialized
  1026.     If Not nmWinInit Then
  1027.       WinIniNotReg
  1028.       Exit Function
  1029.     End If
  1030.  
  1031.   'Write a string to Win.Ini
  1032.     WinPutString = kpWriteProfileString(smWinSection, sEntryName, sValue)
  1033.     WinIniChanged
  1034.  
  1035. End Function
  1036.  
  1037. Function WinPutTF (sEntryName As String, nValue As Integer) As Integer
  1038.   
  1039.   'Set an entry in Win.Ini to True/False
  1040.   'local vars
  1041.     Dim sTF As String
  1042.  
  1043.   'create INI string
  1044.     If nValue Then
  1045.       sTF = "true"
  1046.     Else
  1047.       sTF = "false"
  1048.     End If
  1049.  
  1050.   'write new value
  1051.     WinPutTF = WinPutString(sEntryName, sTF)
  1052.     WinIniChanged
  1053.  
  1054. End Function
  1055.  
  1056. Function WinSectExist () As Integer
  1057.  
  1058.   'Retrieve list of all [Section]'s
  1059.     Dim sSect As String
  1060.     sSect = WinGetSections$()
  1061.     If Len(sSect) = 0 Then
  1062.       WinSectExist = False
  1063.       Exit Function
  1064.     End If
  1065.  
  1066.   'Check for existence registered [Section]
  1067.     sSect = Chr$(0) + UCase$(sSect)
  1068.     If InStr(sSect, Chr$(0) + UCase$(smWinSection) + Chr$(0)) Then
  1069.       WinSectExist = True
  1070.     Else
  1071.       WinSectExist = False
  1072.     End If
  1073.  
  1074. End Function
  1075.  
  1076.