Figure 1: The resource file VIEWBIND.RC for the sample ViewBind utility. #include #include "viewbind.h" VIEWBIND DIALOG LOADONCALL MOVEABLE DISCARDABLE 21, 25, 177, 177 STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX CLASS "ViewBInd" CAPTION "Bindery Viewing Utility" BEGIN CONTROL "", LISTBOX_1, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | WS_BORDER | WS_VSCROLL | WS_TABSTOP | WS_CHILD, 4, 41, 81, 81 CONTROL "", LISTBOX_2, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | WS_BORDER | WS_VSCROLL | WS_TABSTOP | WS_CHILD, 92, 41, 81, 81 CONTROL "", DISPLAY_BOX, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | WS_BORDER | WS_VSCROLL | WS_CHILD, 4, 137, 167, 33 CONTROL "Bindery Object:", 105, "static", SS_LEFT | WS_CHILD, 3, 30, 74, 8 CONTROL "Bindery Property:", 106, "static", SS_LEFT | WS_CHILD, 94, 31, 75, 8 CONTROL "Property Value:", 107, "static", SS_LEFT | WS_CHILD, 5, 127, 156, 9 CONTROL "File Server", FS_BUTTON, "button", BS_RADIOBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 4, 14, 55, 12 CONTROL "Group", GROUP_BUTTON, "button", BS_RADIOBUTTON | WS_TABSTOP | WS_CHILD, 32, 2, 30, 12 CONTROL "User", USER_BUTTON, "button", BS_RADIOBUTTON | WS_TABSTOP | WS_CHILD, 4, 2, 28, 12 END Figure 2: The VIEWBIND.H header file for the sample ViewBind program. #define DISPLAY_BOX 102 #define FS_BUTTON 110 #define GROUP_BUTTON 109 #define LISTBOX_1 100 #define LISTBOX_2 101 #define USER_BUTTON 108 Figure 3: The source code (VIEWBIND.C) for the sample ViewBind program. /***************************************************************************/ /* ViewBind - View the Bindery from a Dialog box */ /* by Charles Rose */ /***************************************************************************/ #include #include #include #include #include "viewbind.h" #define SET 2 #define USER 1 #define GROUP 2 #define SERVER 4 /* Local Prototypes */ long FAR PASCAL WndProc( HWND, unsigned, WORD, LONG ); void DisplayPropertyValue( LONG *propertyValue, char propertyFlags, char PropertyName[16] ); void UpdateObjectListbox( void ); void GetAsciiObjectType( char *szBuffer, int objectType ); void PrintNetAddress( BYTE *netAddress ); /* Global Data */ static HWND hListBox1, hListBox2, hDisplayBox, hUserButton, hGroupButton, hFSButton; static WORD objType = USER; int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow ) { static char szAppName[] = "ViewBind"; MSG msg; HWND hWnd; WNDCLASS wndclass; BYTE i; char szString[50]; int result; /* Register window class and create window */ if ( !hPrevInstance ) { wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground= GetStockObject( WHITE_BRUSH ); wndclass.lpszMenuName= NULL; wndclass.lpszClassName= szAppName; if ( !RegisterClass( &wndclass ) ) return FALSE; } hWnd = CreateDialog( hInstance, szAppName, 0, NULL ); /* Get the window handles of our child windows */ hListBox1 = GetDlgItem( hWnd, LISTBOX_1 ); hListBox2 = GetDlgItem( hWnd, LISTBOX_2 ); hDisplayBox = GetDlgItem( hWnd, DISPLAY_BOX ); hUserButton = GetDlgItem( hWnd, USER_BUTTON ); hGroupButton = GetDlgItem( hWnd, GROUP_BUTTON ); hFSButton = GetDlgItem( hWnd, FS_BUTTON ); /* Set our default button (User) and clear the others */ SendMessage( hUserButton, BM_SETCHECK, 1, 0L ); SendMessage( hGroupButton, BM_SETCHECK, 0, 0L ); SendMessage( hFSButton, BM_SETCHECK, 0, 0L ); /* List the objects in the bindery for the default type (User) */ UpdateObjectListbox(); /* Finally, display the main window and enter the message loop */ ShowWindow( hWnd, nCmdShow ); while ( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam; } long FAR PASCAL WndProc( HWND hWnd, unsigned iMessage, WORD wParam, LONG lParam ) { char szBuffer[50]; char szName[50]; HDC hDC; TEXTMETRIC tm; static short xChar, yChar; static short xClient, yClient; PAINTSTRUCT ps; WORD x; BYTE i; char searchObjectName[48]; WORD searchObjectType; long objectID = -1; char objectHasProperties; char objectFlag; char objectSecurity; int completionCode; char objectName[48]; WORD objectType; char searchPropertyName[16]; long sequenceNumber = -1; char propertyName[16]; char propertyFlags; char propertySecurity; char propertyHasValue; char moreProperties; int segmentNumber = 1; BYTE propertyValue[128]; BYTE moreSegments; switch ( iMessage ) { case WM_SETFOCUS: SetFocus( hListBox1 ); break; case WM_COMMAND: /* If the first listbox was selected and the user selected an item */ if ( ( wParam == LISTBOX_1 ) && ( HIWORD( lParam ) == LBN_SELCHANGE ) ) { /* Get the pos. of the selected item, then place the item in szBuffer */ x = (WORD) SendMessage( hListBox1, LB_GETCURSEL, 0, 0L ); x = (WORD) SendMessage( hListBox1, LB_GETTEXT, x, (LONG) szBuffer ); /* Clear the properties listbox */ SendMessage( hListBox2, LB_RESETCONTENT, 0, 0L ); /* Turn off box redrawing */ SendMessage( hListBox2, WM_SETREDRAW, FALSE, 0L ); /* And add the properties to it */ strcpy( objectName, szBuffer ); objectType = objType; strcpy( searchPropertyName, "*" ); while ( 1 ) { completionCode = ScanProperty( objectName, objectType, searchPropertyName, &sequenceNumber, propertyName, &propertyFlags, &propertySecurity, &propertyHasValue, &moreProperties ); if ( completionCode == 0xFB ) break; /* Use Windows message box facilities if there's an error */ if ( completionCode ) { sprintf( szBuffer, "completionCode = %X", completionCode ); MessageBox( NULL, szBuffer, "ScanProperty", MB_OK | MB_ICONHAND ); break; } SendMessage( hListBox2, LB_ADDSTRING, 0, (LONG) propertyName ); if ( !moreProperties ) break; } /* Update box and turn redrawing back on */ InvalidateRect( hListBox2, NULL, TRUE ); SendMessage( hListBox2, WM_SETREDRAW, TRUE, 0L ); } /* If the property listbox was selected... */ if ( ( wParam == LISTBOX_2 ) && ( HIWORD( lParam ) == LBN_SELCHANGE ) ) { x = (WORD) SendMessage( hListBox1, LB_GETCURSEL, 0, 0L ); x = (WORD) SendMessage( hListBox1, LB_GETTEXT, x, (LONG) objectName ); x = (WORD) SendMessage( hListBox2, LB_GETCURSEL, 0, 0L ); x = (WORD) SendMessage( hListBox2, LB_GETTEXT, x, (LONG) propertyName ); SendMessage( hDisplayBox, LB_RESETCONTENT, 0, 0L ); SendMessage( hDisplayBox, WM_SETREDRAW, FALSE, 0L ); objectType = objType; segmentNumber = 1; while ( 1 ) { completionCode = ReadPropertyValue( objectName, objectType, propertyName, segmentNumber, propertyValue, &moreSegments, &propertyFlags ); if ( ( completionCode == 0xEC ) || ( completionCode == 0xFB ) ) break; if ( completionCode ) { sprintf( szBuffer, "completionCode = %X", completionCode ); MessageBox( NULL, szBuffer, "ReadPropertyValue", MB_OK | MB_ICONHAND ); break; } /* If property was NET_ADDRESS, show it in the Display Box */ if ( !strcmp( propertyName, "NET_ADDRESS" ) ) { PrintNetAddress( propertyValue ); break; } /* If it was a Set (up to 32 4-byte values), show the names */ /* of the bindery objects they represent */ if ( propertyFlags && SET ) for ( x = 0; x < 32; x++ ) { objectID = LongSwap( *((LONG *)(propertyValue + (x*4))) ); if ( !objectID ) break; completionCode = GetBinderyObjectName( objectID, objectName, &objectType ); if ( completionCode ) { sprintf( szBuffer, "completionCode = %X", completionCode ); MessageBox( NULL, szBuffer, "GetBinderyObjectName", MB_OK | MB_ICONHAND ); break; } strcpy( szBuffer, objectName ); GetAsciiObjectType( szName, objectType ); strcat( szBuffer, szName ); SendMessage( hDisplayBox, LB_ADDSTRING, 0, (LONG) szBuffer ); } else if ( !strcmp( propertyName, "IDENTIFICATION" ) ) SendMessage( hDisplayBox, LB_ADDSTRING, 0, (LONG) propertyValue ); else SendMessage( hDisplayBox, LB_ADDSTRING, 0, (LONG) "Value read, Unknown format" ); /* Other cases would go here */ segmentNumber++; } InvalidateRect( hDisplayBox, NULL, TRUE ); SendMessage( hDisplayBox, WM_SETREDRAW, TRUE, 0L ); } /* If a button was hit, set it to on and turn others off, */ /* set the new objectType and re-scan the bindery for the */ /* objects of this new type */ if ( wParam == USER_BUTTON ) { SendMessage( hUserButton, BM_SETCHECK, 1, 0L ); SendMessage( hGroupButton, BM_SETCHECK, 0, 0L ); SendMessage( hFSButton, BM_SETCHECK, 0, 0L ); objType = USER; UpdateObjectListbox(); } if ( wParam == GROUP_BUTTON ) { SendMessage( hUserButton, BM_SETCHECK, 0, 0L ); SendMessage( hGroupButton, BM_SETCHECK, 1, 0L ); SendMessage( hFSButton, BM_SETCHECK, 0, 0L ); objType = GROUP; UpdateObjectListbox(); } if ( wParam == FS_BUTTON ) { SendMessage( hUserButton, BM_SETCHECK, 0, 0L ); SendMessage( hGroupButton, BM_SETCHECK, 0, 0L ); SendMessage( hFSButton, BM_SETCHECK, 1, 0L ); objType = SERVER; UpdateObjectListbox(); } break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, iMessage, wParam, lParam ); } return 0L; } void UpdateObjectListbox( void ) { char szBuffer[50]; int completionCode; char searchObjectName[48]; WORD searchObjectType; long objectID = -1; char objectName[48]; WORD objectType; char objectHasProperties; char objectFlag; char objectSecurity; /* Clear all three listboxes */ SendMessage( hDisplayBox, LB_RESETCONTENT, 0, 0L ); SendMessage( hListBox1, LB_RESETCONTENT, 0, 0L ); SendMessage( hListBox2, LB_RESETCONTENT, 0, 0L ); SendMessage( hListBox1, WM_SETREDRAW, FALSE, 0L ); strcpy( searchObjectName, "*" ); searchObjectType = objType; while ( 1 ) { completionCode = ScanBinderyObject( searchObjectName, searchObjectType, &objectID, objectName, &objectType, &objectHasProperties, &objectFlag, &objectSecurity ); if ( completionCode == 0xFC ) /* No Such Object, i.e. our scan is complete */ break; if ( completionCode ) { sprintf( szBuffer, "completionCode = %X", completionCode ); MessageBox( NULL, szBuffer, "ScanBinderyObject", MB_OK | MB_ICONHAND ); break; } SendMessage( hListBox1, LB_ADDSTRING, 0, (LONG) objectName ); } InvalidateRect( hListBox1, NULL, TRUE ); SendMessage( hListBox1, WM_SETREDRAW, TRUE, 0L ); } void GetAsciiObjectType( char *szBuffer, int objectType ) { *szBuffer = NULL; switch( objectType ) { case 1: strcpy( szBuffer, " (User)" ); break; case 2: strcpy( szBuffer, " (Group)" ); break; case 3: strcpy( szBuffer, " (Print Queue)" ); break; case 4: strcpy( szBuffer, " (File Server)" ); break; default: strcpy( szBuffer, " (Unknown)" ); break; } } void PrintNetAddress( BYTE *netAddress ) { int i; charszAddress[50]; sprintf( szAddress, "%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X:%02X%02X", netAddress[0],netAddress[1],netAddress[2],netAddress[3], netAddress[4],netAddress[5],netAddress[6],netAddress[7], netAddress[8],netAddress[9],netAddress[10], netAddress[11] ); SendMessage( hDisplayBox, LB_ADDSTRING, 0, (LONG) szAddress ); } Figure 4: The make file for ViewBind. viewbind.obj : viewbind.c cl -c -D LINT_ARGS -Gsw -Os -W2 -Zp viewbind.c viewbind.res : viewbind.rc rc -r viewbind.rc viewbind.exe : viewbind.obj viewbind.def viewbind.res link4 viewbind,/align:16, /map, slibw \clib\mslib\snit, viewbind rc viewbind.res Figure 5: The link definition file for ViewBind. NAME VIEWBIND DESCRIPTION'ViewBind -- NetWare Bindery in Dialog Box, C. Rose' STUB 'WINSTUB.EXE' CODE MOVEABLE DATA MOVEABLE MULTIPLE HEAPSIZE 1024 STACKSIZE 4096 EXPORTS WndProc Figure 6: The screen output of ViewBind. [Screen dump of actual Windows list boxes] Cindy--This is currently captured as a PCX file. Can you import these directly into QuarkXPress?