BROWSER.C
//============================================================================= 
//  MODULE: browser.c 
// 
//  Description: 
//  Bloodhound parser DLL for MS Browser 
// 
//  Modification History 
//  Written by Scott Jiles with help from Stevehi 6/94 
//  7/5/94   Fix Periodicity time to zero values when needed. 
//  7/10/94  Fix Server Type bits. 
// 
//============================================================================= 
 
#include "browser.h" 
 
HPROTOCOL hBrowser = NULL; 
 
typedef VOID (WINAPIV *FORMATPROC)(LPPROPERTYINST); 
VOID WINAPI HandleHostAnnounce ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleAnncReq ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleBackReq ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleLocMstrAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleBecomeBackup ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleBackResp ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleMasterAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPIV FormatPeriodicity(LPPROPERTYINST lpPropertyInst ); 
VOID WINAPI HandleElection ( HFRAME hFrame, LPBrowserFRAME BrowserFrame, DWORD BytesLeft ); 
VOID WINAPIV FormatUpTime(LPPROPERTYINST lpPropertyInst ); 
VOID WINAPI HandleReset ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
VOID WINAPI HandleWkGrpAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ); 
 
//============================================================================= 
//  Labeled Browser command set. 
//============================================================================= 
LABELED_BYTE Commands[] = 
{ 
    // first name is defined in .h file.  string will be used to describe 
    // command. 
    { HostAnnouncement,        "Host Announcement [0x01]"}, 
    { AnnouncementRequest,     "Announcement Request [0x02]"}, 
    { Election,                "Election [0x08]"}, 
    { GetBackupListReq,        "Get Backup List Request [0x09]" }, 
    { GetBackupListResp,       "Get Backup List Response [0x0a]" }, 
    { BecomeBackup,            "Become Backup [0x0b]" }, 
    { WkGroupAnnouncement,     "Workgroup Announcement [0x0c]" }, 
    { MasterAnnouncement,      "Master Announcement [0x0d]" }, 
    { ResetBrowserState,       "Reset Browser [0x0e]" }, 
    { LocalMasterAnnouncement, "Local Master Announcement [0x0f]" } 
}; 
 
#define COMMAND_SET_SIZE    (sizeof Commands / sizeof(LABELED_BYTE)) 
 
SET CommandSet = { COMMAND_SET_SIZE, Commands }; 
 
 
//============================================================================= 
//  Labeled Server Type bits used in Announces. 
//============================================================================= 
LABELED_BIT TypeBits[] = 
{ 
  {0, "Not Workstation", "Workstation",}, 
  {1, "Not Server", "Server",}, 
  {2, "Not SQL Server", "SQL Server",}, 
{3, "Not Domain Controller", "Domain Controller",}, 
{4, "Not Backup Controller", "Backup Controller",}, 
{5, "Not Time Source", "Time Source Server",}, 
{6, "Not Apple Server", "Apple Protocol Server",}, 
{7, "Not Novell", "Novell Server",}, 
{8, "Not Domain Member Server", "Domain Member Server",}, 
{9, "Not Print Queue Server", "Print Queue Server",}, 
{10, "Not Dialin Server", "Dialin Server",}, 
{11, "Not Xenix Server", "Xenix Server",}, 
{12, "Not NT System", "Windows NT System",}, 
{13, "Not WFW System", "Windows for Workgroups",}, 
{16, "Not Potential Browser", "Potential Browser Server",}, 
{17, "Not Backup Browser", "Backup Browser Server",}, 
{18, "Not Master Browser", "Master Browser Server",}, 
{19, "Not Domain Master Browser", "Domain Master Browser",}, 
{20, "Not OSF", "OSF",}, 
{21, "Not VMS", "VMS",}, 
{30, "Not Local List Only", "Local List Only",}, 
{31, "Not Domain Enum", "Domain Enum",}, 
}; 
 
SET TypeSet = {sizeof(TypeBits)/sizeof(LABELED_BIT), TypeBits }; 
 
 
//============================================================================= 
//  Labeled bits for Native OS type in Election frames. 
//============================================================================= 
LABELED_BIT OSBits[] = 
{ 
  {0, "Not WFW", "Windows for Workgroups"}, 
  {1, "Not used", "Not used"}, 
  {2, "Not used", "Not used"}, 
  {3, "Not used", "Not used"}, 
  {4, "Not Windows NT Workstation", "Windows NT Workstation",}, 
  {5, "Not Advanced Server", "Advanced Server Windows NT",}, 
{6, "Not used", "Not used"}, 
{7, "Not used", "Not used"}, 
}; 
 
SET OSSet = {sizeof(OSBits)/sizeof(LABELED_BIT), OSBits }; 
 
 
//============================================================================= 
//  Labeled bit set for Election Desire. 
//============================================================================= 
LABELED_BIT DesireBits[] = 
{ 
  {0, "Not Backup Browse Server", "Currently Backup Browse Server"}, 
  {1, "Not Standby Browse Server", "Standby Browser Server"}, 
  {2, "Not Master Browser", "Currently Master Browser Server"}, 
  {3, "Not Domain Master Browser", "Domain Master Browse Server"}, 
{4, "Not used", "Not used"}, 
{5, "Not WINS Client", "Transport Running WINS Client"}, 
{6, "Not used", "Not used"}, 
{7, "Not Advanced Server", "Windows NT Advanced Server"}, 
}; 
 
SET DesireSet = {sizeof(DesireBits)/sizeof(LABELED_BIT), DesireBits }; 
 
 
//============================================================================= 
//  Labeled bits for Reset option bits. 
//============================================================================= 
LABELED_BIT ResetBits[] = 
{ 
  {0, "Zero", "Stop Being Browse Master"}, 
  {1, "Zero", "Reset Entire Browser State"}, 
  {2, "Zero", "Shutdown Browser"}, 
}; 
 
SET ResetSet = {sizeof(ResetBits)/sizeof(LABELED_BIT), ResetBits }; 
 
 
//============================================================================= 
//  Property Table. 
// 
//  Browser database. 
//  The order of the database entry must match the 
//property defines in browser.h 
// 
//============================================================================= 
//#define Browser_COMMAND         0 
//#define Browser_SUMMARY         1 
//#define HA_UpdateCount2 
//#define HA_Periodicity3 
//#define HA_ServerName4 
//#define HA_VersionMajor5 
//#define HA_VersionMinor6 
//#define HA_Type_Flag_Summary7 
//#define HA_Type8 
//#define HA_ElectionVersion9 
//#define HA_Constant10 
//#define AR_Flags11 
//#define AR_Reply12 
//#define BREQ_RequestedCount13 
//#define BREQ_Token14 
//#define BRSP_ServerCnt15 
//#define BRSP_Token16 
//#define BRSP_ServerList17 
//#define MA_MasterName18 
//#define ELEC_Version19 
//#define ELEC_Criteria20 
//#define ELEC_TimeUp21 
//#define ELEC_MustBeZero22 
//#define ELEC_ServerName23 
//#define ELEC_OS_Summary24 
//#define ELEC_OS25 
//#define ELEC_Revision26 
//#define ELEC_Desire_Summary27 
//#define ELEC_Desire28 
//#define RST_Options29 
//#define WKGRP_CommentPtr30 
//#define WKGRP_Comment31 
//#define RST_Options_Summary32 
//============================================================================= 
PROPERTYINFO BrowserDatabase[] = 
{ 
{   // Browser_COMMAND 
0,0, 
"Command", 
"Browser Command", 
PROP_TYPE_BYTE, 
PROP_QUAL_LABELED_SET, 
&CommandSet,// use this if you have labeled set 
64,// avg line length 
FormatPropertyInstance},        // generic format routine 
 
    {   // Browser_Summary 
0,0,                    // handle, label 
"Summary",              // prop name 
"Browser Summary",      // status bar message 
PROP_TYPE_SUMMARY,      // must have special prop type of summary 
PROP_QUAL_LABELED_SET,         // qualifiier 
&CommandSet,                      // address of set struct 
64,                     // max string size of display set 
FormatBrowserSummary},  // instance data - format routine 
 
        {   // HA_UpdateCount 
0,0, 
"Update Count", 
"Incremented when Announce Data Changes.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance},        // generic format routine 
 
 
        {   // HA_Periodicity 
0,0, 
"Periodicity", 
"Announcement cycle in milliseconds.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPeriodicity}, 
 
{   // HA_ServerName 
0,0, 
"Name", 
"Name.", 
PROP_TYPE_STRING,               // use this prop for char data 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // HA_VersionMajor 
0,0, 
"Major Version", 
"Major Version Number.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // HA_VersionMinor 
0,0, 
"Minor Version", 
"Minor Version Number.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // HA_Type_Flag_Summary 
0,0, 
"Server Type Summary", 
"Server Type Summary.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // HA_Type 
0,0, 
"Server Type", 
"Server Type.", 
PROP_TYPE_DWORD, 
PROP_QUAL_FLAGS, 
&TypeSet, 
64 * 22,           // Must have space for all label bits. 
FormatPropertyInstance}, 
 
{   // HA_ElectionVersion 
0,0, 
"Browser Election Version", 
"Browser Election Version.", 
PROP_TYPE_WORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // HA_Constant 
0,0, 
"Browser Constant", 
"Browser Constant.", 
PROP_TYPE_WORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // AR_Flags 
0,0, 
"Unused Flags", 
"Unused Flags.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
 
{   // AR_Reply 
0,0, 
"Reply System Name", 
"Send Reply to this name [Not used for Windows NT].", 
PROP_TYPE_STRING, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // BREQ_RequestedCount 
0,0, 
"Get Backup List Requested Count", 
"Get Backup List Requested Count.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // BREQ_Token 
0,0, 
"Backup Request Token", 
"Correlates Request with Response.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // BRSP_ServerCnt 
0,0, 
"Backup Server Count", 
"Number of Backup Servers returned.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // BRSP_Token 
0,0, 
"Backup Response Token", 
"Correlates Request with Response.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // BRSP_ServerList 
0,0, 
"Backup Servers", 
"List of Backup Servers.", 
PROP_TYPE_STRING, 
PROP_QUAL_NONE, 
0, 
100, 
FormatPropertyInstance}, 
 
 
{   // MA_MasterName 
0,0, 
"Master Name", 
"Master Annoucement Server Name.", 
PROP_TYPE_STRING, 
PROP_QUAL_NONE, 
0, 
100, 
FormatPropertyInstance}, 
 
{   // ELEC_Version 
0,0, 
"Election Version", 
"Election Version.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // ELEC_Criteria 
0,0, 
"Election Criteria", 
"Election Criteria.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
100, 
FormatPropertyInstance}, 
 
{   // ELEC_TimeUp 
0,0, 
"Server Up Time [DD:hh:mm:ss] ", 
"Amount of Time Server has been Running.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
80, 
FormatUpTime}, 
 
{   // ELEC_MustBeZero 
0,0, 
"Must be zero", 
"Must be zero.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
80, 
FormatPropertyInstance}, 
 
{   // ELEC_ServerName 
0,0, 
"Election Server Name", 
"Election Server Name.", 
PROP_TYPE_STRING, 
PROP_QUAL_NONE, 
0, 
80, 
FormatPropertyInstance}, 
 
{   // ELEC_OS_Summary 
0,0, 
"Election OS Summary", 
"Election OS Summary.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // ELEC_OS 
0,0, 
"Native OS", 
"Native Operating System.", 
PROP_TYPE_BYTE, 
PROP_QUAL_FLAGS, 
&OSSet, 
64 * 8,           // Must have space for all label bits. 
FormatPropertyInstance}, 
 
 
{   // ELEC_Revision 
0,0, 
"Election Revision", 
"Election Revision.", 
PROP_TYPE_WORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // ELEC_Desire_Summary 
0,0, 
"Election Desire Summary", 
"Election Desire Summary.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // ELEC_Desire 
0,0, 
"Election Desire", 
"Election Desire.", 
PROP_TYPE_BYTE, 
PROP_QUAL_FLAGS, 
&DesireSet, 
64 * 8,           // Must have space for all label bits. 
FormatPropertyInstance}, 
 
{   // RST_Options 
0,0, 
"Reset Options", 
"Reset Options.", 
PROP_TYPE_BYTE, 
PROP_QUAL_FLAGS, 
&ResetSet, 
64 * 4,           // Must have space for all label bits. 
FormatPropertyInstance}, 
 
{   // WKGRP_CommentPtr 
0,0, 
"Comment Pointer", 
"Comment Pointer.", 
PROP_TYPE_DWORD, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // WKGRP_Comment 
0,0, 
"Server Name", 
"Server Source Name.", 
PROP_TYPE_STRING, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
 
{   // RST_Options_Summary 
0,0, 
"Options Summary", 
"Reset Frame Options Summary.", 
PROP_TYPE_BYTE, 
PROP_QUAL_NONE, 
0, 
64, 
FormatPropertyInstance}, 
}; 
 
DWORD nBrowserProperties = ((sizeof BrowserDatabase) / PROPERTYINFO_SIZE); 
 
 
//============================================================================= 
//  Protocol entry points. 
//============================================================================= 
extern VOID   WINAPI BrowserRegister(HPROTOCOL); 
extern VOID   WINAPI BrowserDeregister(HPROTOCOL); 
extern LPBYTE WINAPI BrowserRecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, LPDWORD, LPHPROTOCOL, LPDWORD); 
extern LPBYTE WINAPI BrowserAttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD); 
extern DWORD  WINAPI BrowserFormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST); 
 
ENTRYPOINTS BrowserEntryPoints = 
{ 
    BrowserRegister, 
    BrowserDeregister, 
    BrowserRecognizeFrame, 
    BrowserAttachProperties, 
    BrowserFormatProperties 
}; 
 
 
//============================================================================= 
//  FUNCTION: BrowserRegister() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
//============================================================================= 
VOID WINAPI BrowserRegister(HPROTOCOL hBrowserProtocol) 
{ 
    register DWORD i; 
 
    //========================================================================= 
    //  Create the property database. 
    //========================================================================= 
 
    CreatePropertyDatabase(hBrowserProtocol, nBrowserProperties); 
 
    for(i = 0; i < nBrowserProperties; ++i) 
    { 
AddProperty(hBrowserProtocol, &BrowserDatabase[i]); 
    } 
} 
 
//============================================================================= 
//  FUNCTION: Deregister() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
//============================================================================= 
VOID WINAPI BrowserDeregister(HPROTOCOL hBrowserProtocol) 
{ 
    DestroyPropertyDatabase(hBrowserProtocol); 
} 
 
//============================================================================= 
//  FUNCTION: BrowserRecognizeFrame() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
//============================================================================= 
LPBYTE WINAPI BrowserRecognizeFrame(HFRAME          hFrame,                     //... frame handle. 
    LPBYTE          MacFrame,                   //... Frame pointer. 
    LPBrowserFRAME  BrowserFrame, 
    DWORD           MacType,                    //... MAC type. 
    DWORD           BytesLeft,                  //... Bytes left. 
    HPROTOCOL       hPreviousProtocol,          //... Previous protocol or NULL if none. 
    DWORD           nPreviousProtocolOffset,    //... Offset of previous protocol. 
    LPDWORD         ProtocolStatusCode,         //... Pointer to return status code in. 
    LPHPROTOCOL     hNextProtocol,              //... Next protocol to call (optional). 
    LPDWORD         InstData)                   //... Next protocol instance data. 
{ 
    // Will only be called if SMB parser finds Transact 
    // with path = \mailslot\browse. 
 
    // Make sure there is some data left. 
    if (BytesLeft == 0) { 
*ProtocolStatusCode = PROTOCOL_STATUS_NOT_RECOGNIZED; 
return (LPBYTE) BrowserFrame; 
    } 
 
    // should probably check bytes left for max and min length. 
    // need to find max and min length. 
    if (BytesLeft < 2 ) { // Reset frame has 2 bytes. 
*ProtocolStatusCode = PROTOCOL_STATUS_NOT_RECOGNIZED; 
return (LPBYTE) BrowserFrame; 
    } 
 
    // Make sure command is between max and min command code. 
    if ((BrowserFrame->command >= HostAnnouncement) & 
       (BrowserFrame->command <= LocalMasterAnnouncement) ) { 
    *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED; 
    return NULL;  //  null means I claim the rest 
    } 
 
    #ifdef DEBUG 
    DebugBreak(); 
    #endif 
 
    // should never hit this point. 
    *ProtocolStatusCode = PROTOCOL_STATUS_NOT_RECOGNIZED; 
    return (LPBYTE) BrowserFrame; 
 
} 
 
//============================================================================= 
//  FUNCTION: BrowserAttachProperties() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
//============================================================================= 
LPBYTE WINAPI BrowserAttachProperties(HFRAME          hFrame, 
      LPBYTE          Frame, 
      LPBrowserFRAME  BrowserFrame, 
      DWORD           MacType, 
      DWORD           BytesLeft, 
      HPROTOCOL       hPreviousProtocol, 
      DWORD           nPreviousProtocolOffset, 
      DWORD           InstData) 
{ 
 
    //========================================================================= 
    //  Attach Summary. 
    //========================================================================= 
 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[Browser_SUMMARY].hProperty, 
   BytesLeft,   // claim the remaining bytes 
   BrowserFrame, 
   0, 0, 0);    // Summary should be 0. 
 
    //========================================================================= 
    //  Attach Command. 
    //========================================================================= 
 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[Browser_COMMAND].hProperty, 
   sizeof(BYTE), 
   BrowserFrame, 
   0, 1, 0);  // Detail other than 0 for drill down. 
 
    switch( BrowserFrame->command ) 
    { 
case HostAnnouncement: 
    HandleHostAnnounce ( hFrame, BrowserFrame ); 
    break; 
 
case AnnouncementRequest: 
    HandleAnncReq ( hFrame, BrowserFrame ); 
    break; 
 
case Election: 
    HandleElection ( hFrame, BrowserFrame, BytesLeft); 
    break; 
 
case GetBackupListReq: 
    HandleBackReq ( hFrame, BrowserFrame ); 
    break; 
 
case GetBackupListResp: 
    HandleBackResp ( hFrame, BrowserFrame ); 
    break; 
 
case BecomeBackup: 
    HandleBecomeBackup ( hFrame, BrowserFrame ); 
    break; 
 
case WkGroupAnnouncement: 
    HandleWkGrpAnnc ( hFrame, BrowserFrame ); 
    break; 
 
case MasterAnnouncement: 
    HandleMasterAnnc ( hFrame, BrowserFrame ); 
    break; 
 
case ResetBrowserState: 
    HandleReset ( hFrame, BrowserFrame ); 
    break; 
 
case LocalMasterAnnouncement: 
    HandleLocMstrAnnc ( hFrame, BrowserFrame ); 
    break; 
 
default: 
    // CommandString = ""; 
    break; 
    } 
    return NULL;  //must return null from attachproperies. 
} 
 
 
/////////////////////////////////////////////////////////////////////////// 
// 
// FormatProperties (Bloodhound parser DLL entrypoint) 
// 
/////////////////////////////////////////////////////////////////////////// 
DWORD WINAPI BrowserFormatProperties(HFRAME hFrame, 
     LPBYTE MacFrame, 
     LPBYTE BrowserFrame, 
     DWORD  nPropertyInsts, 
     LPPROPERTYINST p) 
{ 
    while(nPropertyInsts--) 
    { 
if (p->lpPropertyInfo->InstanceData != NULL ) 
    ((FORMATPROC)p->lpPropertyInfo->InstanceData)(p); 
p++; 
    } 
    return BHERR_SUCCESS; 
} 
 
//============================================================================== 
//  FUNCTION: FormatBrowserSummary() 
// 
//  Modification History 
//  Scottji             6/94        Created 
//  Tom Laird-McConnell 07/20/94    Modified to have more info on summary line 
//  Scottji             07/25/94    Modified Election. Pass BytesLeft.  Add Force. 
//  Tom Laird-McConnell 08/31/94    Converted strings to ANSI 
//============================================================================== 
VOID WINAPIV FormatBrowserSummary(LPPROPERTYINST lpPropertyInst ) 
{ 
    LPBrowserFRAME BrowserFrame; 
//    CHAR * CommandString; 
    char szAnsiName[255]; 
 
    BrowserFrame = (LPBrowserFRAME) lpPropertyInst->lpData; 
 
//    CommandString = (char *) malloc (sizeof(char) * 80); 
 
switch( BrowserFrame->command ) 
{ 
    case HostAnnouncement: 
        { 
            LP_HA_FRAME HA_Frame = (LP_HA_FRAME) BrowserFrame; 
 
            // convert string to ANSI 
            OemToChar( (LPCSTR)&HA_Frame->ServerName, szAnsiName); 
 
            wsprintf(lpPropertyInst->szPropertyText, "%s %s", Commands[0].Label, szAnsiName); 
    break; 
        } 
 
    case AnnouncementRequest: 
        { 
            LP_ANNC_REQ AR_Frame = (LP_ANNC_REQ) BrowserFrame; 
 
            wsprintf(lpPropertyInst->szPropertyText, Commands[1].Label); 
    break; 
        } 
 
    case Election: 
        { 
            LP_ELECTION ELEC_Frame = (LP_ELECTION) BrowserFrame; 
 
            if (ELEC_Frame->Criteria == (ULONG) NULL ) { 
                wsprintf(lpPropertyInst->szPropertyText, "%s [Force]", Commands[2].Label); 
            } 
            else  
            { 
                // convert string to ANSI 
                OemToChar( (LPCSTR)&ELEC_Frame->ServerName, szAnsiName); 
                 
                wsprintf(lpPropertyInst->szPropertyText, "%s %s", Commands[2].Label, szAnsiName); 
            } 
    break; 
        } 
 
    case GetBackupListReq: 
            wsprintf(lpPropertyInst->szPropertyText, Commands[3].Label); 
    break; 
 
    case GetBackupListResp: 
        { 
            LP_BACK_RESP BRSP_Frame = (LP_BACK_RESP) BrowserFrame; 
 
            wsprintf(lpPropertyInst->szPropertyText, "%s %d Servers", Commands[4].Label, BRSP_Frame->BackupServerCount); 
    break; 
        } 
 
    case BecomeBackup: 
        { 
            LP_BECOME_BACKUP BB_Frame = (LP_BECOME_BACKUP) BrowserFrame; 
 
            // convert string to ANSI 
            OemToChar( (LPCSTR)&BB_Frame->BrowserToPromote, szAnsiName); 
             
            wsprintf(lpPropertyInst->szPropertyText, "%s Name = %s",  Commands[5].Label, szAnsiName); 
    break; 
        } 
 
    case WkGroupAnnouncement: 
        { 
            LP_WKGRP_FRAME WKGRP_Frame = (LP_WKGRP_FRAME) BrowserFrame; 
 
            // convert string to ANSI 
            OemToChar( (LPCSTR)&WKGRP_Frame->ServerName, szAnsiName); 
             
            wsprintf(lpPropertyInst->szPropertyText, "%s %s", Commands[6].Label, szAnsiName); 
    break; 
        } 
 
    case MasterAnnouncement: 
        { 
            LP_MASTER_ANNC MA_Frame = (LP_MASTER_ANNC) BrowserFrame; 
 
            // convert string to ANSI 
            OemToChar( (LPCSTR)&MA_Frame->MasterName, szAnsiName); 
 
            wsprintf(lpPropertyInst->szPropertyText, "%s %s", Commands[7].Label, szAnsiName); 
    break; 
        } 
 
    case ResetBrowserState: 
            wsprintf(lpPropertyInst->szPropertyText, Commands[8].Label); 
    break; 
 
    case LocalMasterAnnouncement: 
        { 
            LP_HA_FRAME HA_Frame = (LP_HA_FRAME) BrowserFrame; 
 
            // convert string to ANSI 
            OemToChar( (LPCSTR)&HA_Frame->ServerName, szAnsiName); 
 
            wsprintf(lpPropertyInst->szPropertyText, "%s %s", Commands[9].Label, szAnsiName); 
    break; 
        } 
 
    default: 
            wsprintf(lpPropertyInst->szPropertyText, "Unknown Command?"); 
    break; 
} 
} 
 
 
 
 
//============================================================================== 
//  FUNCTION: HandleHostAnnouce() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleHostAnnounce ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_HA_FRAME HA_Frame; 
 
    // HA Update Count 
    HA_Frame = (LP_HA_FRAME) BrowserFrame; 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_UpdateCount].hProperty, 
   sizeof(BYTE), 
   &HA_Frame->UpdateCount, 
   0, 1, 0); 
    // Periodicity;     announcement cycle in milliseconds 
    HA_Frame = (LP_HA_FRAME) BrowserFrame; 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Periodicity].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Periodicity, 
   0, 1, 0); 
    // HA_ServerName 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ServerName].hProperty, 
   LM20_CNLEN+1, 
   &HA_Frame->ServerName, 
   0, 1, 0); 
    // HA_VersionMajor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMajor].hProperty, 
   sizeof(BYTE), 
   &HA_Frame->VersionMajor, 
   0, 1, 0); 
    // HA_VersionMinor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMinor].hProperty, 
   sizeof(BYTE), 
   &HA_Frame->VersionMinor, 
   0, 1, 0); 
    // HA_Type_Flag_Summary 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type_Flag_Summary].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Type, 
   0, 1, 0); 
    // HA_Type 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Type, 
   0, 2, 0); 
    // HA_ElectionVersion 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ElectionVersion].hProperty, 
   sizeof(WORD), 
   &HA_Frame->HAElectionVersion, 
   0, 1, 0); 
    // HA_Constant 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Constant].hProperty, 
   sizeof(WORD), 
   &HA_Frame->HAConstant, 
   0, 1, 0); 
} 
 
//============================================================================== 
//  FUNCTION: HandleAnncReq() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
 
VOID WINAPI HandleAnncReq ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_ANNC_REQ AR_Frame; 
    int len; 
 
    AR_Frame = (LP_ANNC_REQ) BrowserFrame; 
 
    // AR_Flags 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[AR_Flags].hProperty, 
   sizeof(UCHAR), 
   &AR_Frame->Flags, 
   0, 1, 0); 
    len = strlen ( &AR_Frame->Reply[0] ); 
    // AR_Reply 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[AR_Reply].hProperty, 
   len, 
   &AR_Frame->Reply, 
   0, 1, 0); 
} 
 
//============================================================================== 
//  FUNCTION: HandleBackReq() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleBackReq ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_BACK_REQ_FRAME BREQ_Frame; 
 
    BREQ_Frame = (LP_BACK_REQ_FRAME) BrowserFrame; 
 
    // BREQ_RequestedCount 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[BREQ_RequestedCount].hProperty, 
   sizeof(UCHAR), 
   &BREQ_Frame->RequestedCount, 
   0, 1, 0); 
    // BREQ_Token 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[BREQ_Token].hProperty, 
   sizeof(LONG), 
   &BREQ_Frame->Token, 
   0, 1, 0); 
} 
 
//============================================================================== 
//  FUNCTION: HandleLocMstrAnnc() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleLocMstrAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_HA_FRAME HA_Frame; 
 
    //========================================================================= 
    //  Same as Host Announcement frame. 
    //========================================================================= 
 
    // HA Update Count 
    HA_Frame = (LP_HA_FRAME) BrowserFrame; 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_UpdateCount].hProperty, 
   sizeof(BYTE), 
&HA_Frame->UpdateCount, 
   0, 1, 0); 
    // Periodicity;     announcement cycle in milliseconds 
 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Periodicity].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Periodicity, 
   0, 1, 0); 
    // HA_ServerName 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ServerName].hProperty, 
   LM20_CNLEN+1, 
   &HA_Frame->ServerName, 
   0, 1, 0); 
    // HA_VersionMajor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMajor].hProperty, 
   sizeof(BYTE), 
   &HA_Frame->VersionMajor, 
   0, 1, 0); 
    // HA_VersionMinor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMinor].hProperty, 
   sizeof(BYTE), 
   &HA_Frame->VersionMinor, 
   0, 1, 0); 
    // HA_Type_Flag_Summary 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type_Flag_Summary].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Type, 
   0, 1, 0); 
    // HA_Type 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type].hProperty, 
   sizeof(ULONG), 
   &HA_Frame->Type, 
   0, 2, 0); 
    // HA_ElectionVersion 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ElectionVersion].hProperty, 
   sizeof(WORD), 
   &HA_Frame->HAElectionVersion, 
   0, 1, 0); 
    // HA_Constant 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Constant].hProperty, 
   sizeof(WORD), 
   &HA_Frame->HAConstant, 
   0, 1, 0); 
} 
 
//============================================================================== 
//  FUNCTION: HandleBecomeBackup() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleBecomeBackup ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_BECOME_BACKUP BB_Frame; 
    int len; 
 
    BB_Frame = (LP_BECOME_BACKUP) BrowserFrame; 
 
    // BrowserToPromote = HA_ServerName 
    len = strlen ( &BB_Frame->BrowserToPromote[0] ); 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ServerName].hProperty, 
   len, 
   &BB_Frame->BrowserToPromote, 
   0, 1, 0); 
} 
 
 
//============================================================================== 
//  FUNCTION: HandleBackResp() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleBackResp ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_BACK_RESP BRSP_Frame; 
    int i, k, len, offset; 
 
    BRSP_Frame = (LP_BACK_RESP) BrowserFrame; 
    i = (int)BRSP_Frame->BackupServerCount; 
 
    // BRSP_ServerCnt 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[BRSP_ServerCnt].hProperty, 
   sizeof(UCHAR), 
   &BRSP_Frame->BackupServerCount, 
   0, 1, 0); 
    // BRSP_Token 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[BRSP_Token].hProperty, 
   sizeof(ULONG), 
   &BRSP_Frame->Token, 
   0, 1, 0); 
 
    for (k = 1, offset = 0 ; k <= i; k++) { 
        len = strlen ( &BRSP_Frame->BackupServerList[offset] ); 
        // BRSP_ServerList 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[BRSP_ServerList].hProperty, 
   len, 
   &BRSP_Frame->BackupServerList[offset], 
   0, 1, 0); 
        offset = offset + 1 + strlen( (UCHAR *) &BRSP_Frame->BackupServerList[offset] ); 
    } 
} 
 
//============================================================================== 
//  FUNCTION: HandleMasterAnnc() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleMasterAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_MASTER_ANNC MA_Frame; 
    int len; 
 
    MA_Frame = (LP_MASTER_ANNC) BrowserFrame; 
    len = strlen ( &MA_Frame->MasterName[0] ); 
 
    // MA_MasterName 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[MA_MasterName].hProperty, 
   len, 
   &MA_Frame->MasterName, 
   0, 1, 0); 
} 
 
//============================================================================== 
//  FUNCTION: FormatPeriodicity() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPIV FormatPeriodicity(LPPROPERTYINST lpPropertyInst ) 
{ 
    ULPDWORD period; 
    ULONG value; 
    char CommandString[80]; 
 
    period =  (ULPDWORD)lpPropertyInst->lpData; 
    value = (((ULONG)* period) / 1000) /60 ; 
    _ultoa (value, CommandString, 10); 
    strcpy (lpPropertyInst->szPropertyText, "Annoucement Interval [minutes] = "); 
    strcat ( lpPropertyInst->szPropertyText, CommandString ); 
} 
 
//============================================================================== 
//  FUNCTION: HandleElection() 
// 
//  Modification History 
//  Written by Scottji 6/94 
//  Scottji             07/25/94    Modified Election. Add Force. 
//                                  Pass BytesLeft.  Check length before attach. 
// 
//============================================================================== 
VOID WINAPI HandleElection ( HFRAME hFrame, LPBrowserFRAME BrowserFrame, DWORD BytesLeft ) 
{ 
    LP_ELECTION ELEC_Frame; 
    int len; 
    char *p; 
 
    ELEC_Frame = (LP_ELECTION) BrowserFrame; 
    len = strlen ( &ELEC_Frame->ServerName[0] ); 
 
    if (BytesLeft >= 2 ) { 
        // ELEC_Version 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_Version].hProperty, 
   sizeof(BYTE), 
   &ELEC_Frame->Version, 
   0, 1, 0); 
    } 
 
    if (BytesLeft >= 6  ) { 
        // ELEC_Criteria 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_Criteria].hProperty, 
   sizeof(DWORD), 
   &ELEC_Frame->Criteria, 
   0, 1, 0); 
 
        p = (char *) &ELEC_Frame->Criteria; 
        // ELEC_OS_Summary 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_OS_Summary].hProperty, 
   sizeof(BYTE), 
   p+3, 
   0, 2, 0); 
        // ELEC_OS 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_OS].hProperty, 
   sizeof(BYTE), 
   p+3, 
   0, 3, 0); 
        // ELEC_Revision 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_Revision].hProperty, 
   sizeof(WORD), 
   p+1, 
   0, 2, 0); 
        // ELEC_Desire_Summary 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_Desire_Summary].hProperty, 
   sizeof(BYTE), 
   p, 
   0, 2, 0); 
 
        // ELEC_Desire 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_Desire].hProperty, 
   sizeof(BYTE), 
   p, 
   0, 3, 0); 
    } 
 
    if (BytesLeft >= 10 ) { 
        // ELEC_TimeUp 
        AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_TimeUp].hProperty, 
   sizeof(DWORD), 
   &ELEC_Frame->TimeUp, 
   0, 1, 0); 
    } 
 
    if ((BytesLeft > 14 ) & (BytesLeft <50 ) ) { 
    // ELEC_ServerName 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[ELEC_ServerName].hProperty, 
   len, 
   &ELEC_Frame->ServerName, 
   0, 1, 0); 
    } 
} 
 
//============================================================================== 
//  FUNCTION: FormatUpTime() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPIV FormatUpTime(LPPROPERTYINST lpPropertyInst ) 
{ 
    ULPDWORD value; 
    ULONG time, days, hours, minutes, seconds; 
    char CommandString[80]; 
    ULONG ONEDAY, ONEHOUR, ONEMINUTE; 
 
    ONEDAY =   86400000; 
    ONEHOUR =  3600000; 
    ONEMINUTE =  60000; 
    value =  (ULPDWORD)lpPropertyInst->lpData; 
    time = (ULONG) *value; 
 
    if (time >= ONEDAY) { 
        days = time / ONEDAY; 
        time = time - (days * ONEDAY); 
    } 
    else { 
        days = 0; 
    } 
    if (time >= ONEHOUR){ 
        hours = time / ONEHOUR; 
        time = time - (hours * ONEHOUR); 
    } 
    else { 
        hours = 0; 
    } 
    if (time >= ONEMINUTE) { 
        minutes = time / ONEMINUTE; 
        time = time - (minutes * ONEMINUTE); 
    } 
    else { 
        minutes = 0; 
    } 
    if(seconds != 0) { 
        seconds = time / 1000; 
    } 
    else { 
        seconds = 0; 
    } 
 
    strcpy (lpPropertyInst->szPropertyText, "Server Up Time [DD:hh:mm:ss] "); 
    if( (ULONG)*value != 0 ) { 
    _ultoa (days, CommandString, 10); 
    strcat (lpPropertyInst->szPropertyText, CommandString ); 
    strcat (lpPropertyInst->szPropertyText, ":"); 
    _ultoa (hours, CommandString, 10); 
    strcat (lpPropertyInst->szPropertyText, CommandString ); 
    strcat (lpPropertyInst->szPropertyText, ":"); 
    _ultoa (minutes, CommandString, 10); 
    strcat (lpPropertyInst->szPropertyText, CommandString ); 
    strcat (lpPropertyInst->szPropertyText, ":"); 
    _ultoa (seconds, CommandString, 10); 
    strcat (lpPropertyInst->szPropertyText, CommandString ); 
    } 
    else { 
    strcat (lpPropertyInst->szPropertyText, "Null"); 
 } 
} 
 
//============================================================================== 
//  FUNCTION: HandleReset() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleReset ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_RESET RST_Frame; 
 
    RST_Frame = (LP_RESET) BrowserFrame; 
 
 
    // RST_Options_Summary 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[RST_Options_Summary].hProperty, 
   sizeof(BYTE), 
   &RST_Frame->Options, 
   0, 1, 0); 
    // RST_Options 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[RST_Options].hProperty, 
   sizeof(BYTE), 
   &RST_Frame->Options, 
   0, 2, 0); 
} 
 
 
//============================================================================== 
//  FUNCTION: HandleWkGrpAnnc() 
// 
//  Modification History 
//  Written by Scottji 6/94 
// 
// 
//============================================================================== 
VOID WINAPI HandleWkGrpAnnc ( HFRAME hFrame, LPBrowserFRAME BrowserFrame ) 
{ 
    LP_WKGRP_FRAME WKGRP_Frame; 
    int len; 
 
    //========================================================================= 
    //  Same as Host Announcement frame. 
    //========================================================================= 
 
    WKGRP_Frame = (LP_WKGRP_FRAME) BrowserFrame; 
    //  Update Count 
 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_UpdateCount].hProperty, 
   sizeof(BYTE), 
   &WKGRP_Frame->UpdateCount, 
   0, 1, 0); 
    // Periodicity;     announcement cycle in milliseconds 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Periodicity].hProperty, 
   sizeof(ULONG), 
   &WKGRP_Frame->Periodicity, 
   0, 1, 0); 
    // ServerName 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_ServerName].hProperty, 
   LM20_CNLEN+1, 
   &WKGRP_Frame->ServerName, 
   0, 1, 0); 
    // VersionMajor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMajor].hProperty, 
   sizeof(BYTE), 
   &WKGRP_Frame->VersionMajor, 
   0, 1, 0); 
    // VersionMinor 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_VersionMinor].hProperty, 
   sizeof(BYTE), 
   &WKGRP_Frame->VersionMinor, 
   0, 1, 0); 
    // Type_Flag_Summary 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type_Flag_Summary].hProperty, 
   sizeof(ULONG), 
   &WKGRP_Frame->Type, 
   0, 1, 0); 
    // Type 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[HA_Type].hProperty, 
   sizeof(ULONG), 
   &WKGRP_Frame->Type, 
   0, 2, 0); 
    // WKGRP_CommentPtr 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[WKGRP_CommentPtr].hProperty, 
   sizeof(DWORD), 
   &WKGRP_Frame->CommentPtr, 
   0, 1, 0); 
    len = strlen ( &WKGRP_Frame->Comment[0] ); 
    // WKGRP_Comment 
    AttachPropertyInstance(hFrame, 
   BrowserDatabase[WKGRP_Comment].hProperty, 
   len, 
   &WKGRP_Frame->Comment, 
   0, 1, 0); 
}