home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / wndsvw.exe / WDSVIEW.C next >
Text File  |  1995-03-27  |  33KB  |  1,018 lines

  1. /****************************************************************************
  2. **    File:    WDSVIEW.C
  3. **
  4. **    Desc:    This program is used as a viewer for Novell's Directory Services.
  5. **                The objects shown may vary depending on users rights to the Tree.
  6. **
  7. **        DISCLAIMER
  8. **
  9. **    Novell, Inc. makes no representations or warranties with respect to
  10. **    any NetWare software, and specifically disclaims any express or
  11. **    implied warranties of merchantability, title, or fitness for a
  12. **    particular purpose.
  13. **
  14. **    Distribution of any NetWare software is forbidden without the
  15. **    express written consent of Novell, Inc.  Further, Novell reserves
  16. **    the right to discontinue distribution of any NetWare software.
  17. **
  18. **    Novell is not responsible for lost profits or revenue, loss of use
  19. **    of the software, loss of data, costs of re-creating lost data, the
  20. **    cost of any substitute equipment or program, or claims by any party
  21. **    other than you.  Novell strongly recommends a backup be made before
  22. **    any software is installed.   Technical support for this software
  23. **    may be provided at the discretion of Novell.
  24. **
  25. **    History:
  26. **
  27. **        When            Who    What
  28. **        -----------------------------------------------------------------------
  29. **        03-07-95    CRG    Original code adapted from dsview.c
  30. */
  31.  
  32. #define NWWIN
  33. #define wm_initwindow    (WM_USER + 1)
  34. /***************************************************************************
  35. **  Libraries Linked in for .exe
  36. **
  37. **  NWCALLS.LIB
  38. **  NWNET.LIB
  39. **
  40. */
  41.  
  42. /****************************************************************************
  43. **    Include headers, macros, function prototypes, etc.
  44. */
  45.  
  46.     /*------------------------------------------------------------------------
  47.     **    ANSI
  48.     */
  49.     #include <windows.h>
  50.     #include <dos.h>
  51.     #include <io.h>
  52.     #include <toolhelp.h>
  53.     #include <stdlib.h>
  54.     #include <string.h>
  55.     #include <stdio.h>
  56.     #include <ctype.h>
  57.     #include <malloc.h>
  58.  
  59.  
  60.     /*------------------------------------------------------------------------
  61.     **    NetWare
  62.     */
  63.     #include <nwnet.h>
  64.     #include <nwcalls.h>
  65.  
  66.     /*------------------------------------------------------------------------
  67.     **    Program
  68.     */
  69.     #include "wdsview.h"
  70.  
  71.     /*------------------------------------------------------------------------
  72.     **    Prototypes
  73.     */
  74.     long FAR PASCAL _export WndProc(HWND, UINT, UINT, LONG);
  75.     long InitDSStuff(HWND hwnd);
  76.     long InitMainDialog(HWND hwnd);
  77.     long FreeDSStuff(void);
  78.     long RefreshObjects(HWND hwnd);
  79.     long HandleCcode(HWND hwnd, NWDSCCODE ccode, char *procName);
  80.     long RefreshAttributes(HWND hwnd);
  81.     void DecodeRights(char *attrName, char *rightsstring, NWDS_PRIVILEGES    privs);
  82.     WORD UpdateValueListBox(HWND hwnd);
  83.     WORD ShowChangeContextDialog(HWND hDlg);
  84.     BOOL CALLBACK CContextDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam);
  85.     WORD UpdateCContextDialog(HWND hDlg);
  86.     WORD UpdateChangedContext(HWND hDlg);
  87.     WORD ShowAboutDialog(HWND hDlg);
  88.     BOOL CALLBACK AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam);
  89.  
  90.  
  91.     /*------------------------------------------------------------------------
  92.     **    Globals
  93.     */
  94.     char                                nContext[MAX_DN_CHARS];
  95.     NWDSContextHandle        gContext;
  96.     HANDLE    hInst;
  97.  
  98.  
  99.  
  100. /***************************************************************************
  101. **  This is the main entry point.  This is standard for all Windows Apps.
  102. */
  103. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  104.                                         LPSTR lpszCmdLine, int nCmdShow)
  105. {
  106.     static char    szAppName[] = "WDSView";
  107.     HWND                hwnd;
  108.     MSG                    msg;
  109.     WNDCLASS        wndclass;
  110.  
  111.     if(!hPrevInstance)
  112.     {
  113.         wndclass.style                    = CS_HREDRAW | CS_VREDRAW;
  114.         wndclass.lpfnWndProc        =    WndProc;
  115.         wndclass.cbClsExtra            =    0;
  116.         wndclass.cbWndExtra            =    DLGWINDOWEXTRA;
  117.         wndclass.hInstance            =    hInstance;
  118.         wndclass.hIcon                    =    LoadIcon(hInstance, szAppName);
  119.         wndclass.hCursor                = LoadCursor(NULL, IDC_ARROW);
  120.         wndclass.hbrBackground    = COLOR_WINDOW + 1;
  121.         wndclass.lpszMenuName        =    NULL;
  122.         wndclass.lpszClassName    = szAppName;
  123.  
  124.         RegisterClass(&wndclass);
  125.     }
  126.     hInst = hInstance;
  127.     hwnd = CreateDialog(hInstance, szAppName, 0, NULL);
  128.     SendMessage(hwnd, wm_initwindow, NULL, NULL);
  129.     ShowWindow(hwnd, nCmdShow);
  130.     while(GetMessage(&msg, NULL, 0,0))
  131.     {
  132.         TranslateMessage(&msg);
  133.         DispatchMessage(&msg);
  134.     }
  135.     return msg.wParam;
  136. }
  137.  
  138.  
  139.  
  140. /***************************************************************************
  141. **  This is the process to handle all messages for the main window.
  142. */
  143. long FAR PASCAL _export WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
  144. {
  145.     switch(message)
  146.     {
  147.         case WM_CREATE:
  148.             if(InitDSStuff(hwnd))
  149.             {
  150.                 DestroyWindow(hwnd);
  151.             }
  152.             break;
  153.         case wm_initwindow:
  154.             InitMainDialog(hwnd);
  155.             break;
  156.         case WM_COMMAND :
  157.             switch (wParam)
  158.             {
  159.                 case CM_FILEEXIT:
  160.                     DestroyWindow(hwnd);
  161.                     break;
  162.                 case CM_CHANGECON:
  163.                 case IDC_CCONTEXT:
  164.                     ShowChangeContextDialog(hwnd);
  165.                     RefreshObjects(hwnd);
  166.                     break;
  167.                 case IDC_OBJECTS:
  168.                     if (HIWORD (lParam) == LBN_SELCHANGE)
  169.                     {
  170.                         RefreshAttributes(hwnd);
  171.                     }
  172.                     break;
  173.                 case IDC_ATTRIBUTES:
  174.                     if (HIWORD (lParam) == LBN_SELCHANGE)
  175.                     {
  176.                         UpdateValueListBox(hwnd);
  177.                     }
  178.                     break;
  179.                 case CM_HELPABOUT:
  180.                     ShowAboutDialog(hwnd);
  181.                     break;
  182.             }
  183.             return 0;
  184.         case WM_DESTROY :
  185.                 FreeDSStuff();
  186.                 PostQuitMessage(0);
  187.                 return 0;
  188.     }
  189.     return DefWindowProc(hwnd, message, wParam, lParam);
  190. }
  191.  
  192.  
  193.  
  194. /***************************************************************************
  195. **  This procedure will create the context used globaly in this application
  196. **    and set the context flags to the appropriate settings.  No unicode
  197. **    table operations are performed because this app uses the defualt
  198. **    which is loaded by the NetWare.drv.
  199. */
  200. long InitDSStuff(HWND hwnd)
  201. {
  202.     NWDSCCODE      ccode;
  203.     DWORD              flags;
  204.  
  205.     gContext = NWDSCreateContext();
  206.     if((int)gContext == ERR_CONTEXT_CREATION)
  207.     {
  208.         MessageBox(hwnd, "Create Context Failed with 'ERR_CONTEXT_CREATION'", "WDSVIEW Error", MB_OK);
  209.         return((WORD)gContext);
  210.     }
  211.     ccode = NWDSGetContext(gContext, DCK_FLAGS, &flags);
  212.     if(ccode < 0)
  213.     {
  214.         HandleCcode(hwnd, ccode, "NWDSGetContext");
  215.         return(ccode);
  216.     }
  217.     /* Turning off Types for all names. (ie: is.novell not ou=is.o=novell) */
  218.     flags |= DCV_TYPELESS_NAMES;
  219.     ccode = NWDSSetContext(gContext, DCK_FLAGS, &flags);
  220.     if(ccode < 0)
  221.     {
  222.         HandleCcode(hwnd, ccode, "NWDSSetContext");
  223.         return(ccode);
  224.     }
  225.     ccode = NWDSGetContext(gContext, DCK_NAME_CONTEXT, nContext);
  226.     if(ccode <0)
  227.     {
  228.         HandleCcode(hwnd, ccode, "NWDSGetContext");
  229.         return(ccode);
  230.     }
  231.     return 0;
  232. }
  233.  
  234.  
  235.  
  236. /***************************************************************************
  237. **  Freeing up the context at the end of the application.
  238. */
  239. long FreeDSStuff(void)
  240. {
  241.     NWDSCCODE    ccode;
  242.  
  243.     ccode = NWDSFreeContext(gContext);
  244.     if(ccode < 0)
  245.     {
  246.         return(ccode);
  247.     }
  248.     return 0;
  249. }
  250.  
  251.  
  252.  
  253. /***************************************************************************
  254. **  This is used to initialize the controls on the main window.  The current
  255. **    context field is set here and the list of objects in the current container
  256. **    (or context) is filled.
  257. */
  258. long InitMainDialog(HWND hwnd)
  259. {
  260.     SetDlgItemText(hwnd, IDC_CONTAINER, nContext);
  261.     RefreshObjects(hwnd);
  262.     return 0;
  263. }
  264.  
  265.  
  266.  
  267. /***************************************************************************
  268. **  This is a generic error handling routine.  It pops up a windows showing
  269. **    the message and error code passed in.
  270. */
  271. long HandleCcode(HWND hwnd, NWDSCCODE ccode, char *procName)
  272. {
  273.     char message[100];
  274.  
  275.     sprintf(message,"%s returned code: 0x%X", procName, ccode);
  276.     MessageBox(hwnd, message, "WDSVIEW Error", MB_OK);
  277.     return 0;
  278. };
  279.  
  280.  
  281.  
  282. /***************************************************************************
  283. **  This creates a process to handle a second dialog window and then creates
  284. **    the dialog.  Used here to change the context.
  285. */
  286. WORD ShowChangeContextDialog(HWND hDlg)
  287. {
  288.     static FARPROC lpfnCContextDlgProc;
  289.     lpfnCContextDlgProc = MakeProcInstance((FARPROC)CContextDlgProc, hInst);
  290.     DialogBox(hInst, "ChangeContext", GetActiveWindow(), lpfnCContextDlgProc);
  291.     FreeProcInstance(lpfnCContextDlgProc);
  292.  return FALSE;
  293. }
  294.  
  295.  
  296.  
  297. /***************************************************************************
  298. **  This process handles all messages sent to the popup dialog windows used
  299. **    to change the context.
  300. */
  301. BOOL CALLBACK CContextDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
  302. {
  303.     char                              container[MAX_DN_CHARS];
  304.     switch (message)
  305.     {
  306.         case WM_CLOSE:
  307.             GetDlgItemText(hDlg, IDC_CURRENT_CONTEXT, container, MAX_DN_CHARS);
  308.             SetDlgItemText(GetParent(hDlg), IDC_CONTAINER, container);
  309.             EndDialog (hDlg, 0);
  310.             return TRUE;
  311.         case WM_INITDIALOG:
  312.             UpdateCContextDialog(hDlg);
  313.             return TRUE;
  314.         case WM_COMMAND:
  315.             switch (wParam)
  316.             {
  317.                 case IDC_CONTAINER_LIST:
  318.                     if (HIWORD (lParam) == LBN_DBLCLK) /* Double Click*/
  319.                     {
  320.                         UpdateChangedContext(hDlg);
  321.                         UpdateCContextDialog(hDlg);
  322.                     }
  323.                     break;
  324.                 case SELECT_BUT:
  325.                     GetDlgItemText(hDlg, IDC_CURRENT_CONTEXT, container, MAX_DN_CHARS);
  326.                     SetDlgItemText(GetParent(hDlg), IDC_CONTAINER, container);
  327.                     EndDialog (hDlg, 0);
  328.                     return TRUE;
  329.             }
  330.             break;
  331.     }
  332.     return FALSE;
  333. }
  334.  
  335.  
  336.  
  337. /***************************************************************************
  338. **  Updates the popup dialog for Change Context so that the current list of
  339. **    Containers is displayed.
  340. */
  341. WORD UpdateCContextDialog(HWND hDlg)
  342. {
  343.     NWDS_BUFFER                    *outBuf;
  344.     NWDS_ITERATION                iterationHandle = -1L;
  345.     NWDSCCODE                    ccode;
  346.     NWCOUNT                        objectCount, attrCount,i;
  347.     NWOBJECT_INFO                objectInfo;
  348.     char                              objectName[MAX_DN_CHARS];
  349.  
  350.  
  351.     SendDlgItemMessage(hDlg, IDC_CONTAINER_LIST, LB_RESETCONTENT, 0, 0);
  352.     SetDlgItemText(hDlg, IDC_CURRENT_CONTEXT, nContext);
  353.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  354.     if(ccode < 0)
  355.     {
  356.         HandleCcode(hDlg, ccode, "NWDSAllocBuf");
  357.         return(TRUE);
  358.     }
  359.     do
  360.     {
  361.         ccode = NWDSList(gContext,
  362.                                     "",
  363.                                     &iterationHandle,
  364.                                     outBuf);
  365.         if(ccode < 0)
  366.         {
  367.             HandleCcode(hDlg, ccode, "NWDSList");
  368.             NWDSFreeBuf(outBuf);
  369.             return(TRUE);
  370.         }
  371.         ccode = NWDSGetObjectCount(gContext,
  372.                                             outBuf,
  373.                                             &objectCount);
  374.         if(ccode < 0)
  375.         {
  376.             HandleCcode(hDlg, ccode ,"NWDSGetObjectCount");
  377.             NWDSFreeBuf(outBuf);
  378.             return(TRUE);
  379.         }
  380.         for(i=0; i<objectCount; i++)
  381.         {
  382.             ccode = NWDSGetObjectName(gContext,
  383.                                                 outBuf,
  384.                                                 objectName,
  385.                                                 &attrCount,
  386.                                                 &objectInfo);
  387.             if(ccode < 0)
  388.             {
  389.                 HandleCcode(hDlg, ccode, "NWDSGetObjectName");
  390.                 NWDSFreeBuf(outBuf);
  391.                 return(TRUE);
  392.             }
  393.             if(objectInfo.objectFlags & DS_CONTAINER_ENTRY)
  394.                 SendDlgItemMessage(hDlg, IDC_CONTAINER_LIST, LB_ADDSTRING, 0,
  395.                             (LONG) (LPSTR) objectName);
  396.         }
  397.     }
  398.     while(iterationHandle != -1);
  399.     if(strcmp("[Root]", nContext))
  400.         SendDlgItemMessage(hDlg, IDC_CONTAINER_LIST, LB_ADDSTRING, 0,
  401.             (LONG) (LPSTR) "..");
  402.     NWDSFreeBuf(outBuf);
  403.     return(FALSE);
  404. }
  405.  
  406.  
  407.  
  408. /***************************************************************************
  409. **  Changes the global context for the app when a new container is selected
  410. */
  411. WORD UpdateChangedContext(HWND hDlg)
  412. {
  413.     NWDSCCODE                    ccode;
  414.     char                            contextName[MAX_DN_CHARS];
  415.     char                            contextCName[MAX_DN_CHARS];
  416.     WORD                            n;
  417.  
  418.     n = (WORD) SendDlgItemMessage(hDlg, IDC_CONTAINER_LIST, LB_GETCURSEL, 0, 0L);
  419.     SendDlgItemMessage(hDlg, IDC_CONTAINER_LIST, LB_GETTEXT, n,
  420.                         (LONG) (LPSTR) contextName);
  421.     if(!strcmp("..", contextName))
  422.         strcpy(contextName, ".");
  423.     ccode = NWDSCanonicalizeName(gContext, contextName, contextCName);
  424.     if(ccode < 0)
  425.     {
  426.         HandleCcode(hDlg, ccode, "NWDSCanonicalizeName");
  427.         return(ccode);
  428.     }
  429.     ccode = NWDSSetContext(gContext, DCK_NAME_CONTEXT, (void *)contextCName);
  430.     if(ccode < 0)
  431.     {
  432.         HandleCcode(hDlg, ccode, "NWDSSetContext");
  433.         return(ccode);
  434.     }
  435.     ccode = NWDSGetContext(gContext, DCK_NAME_CONTEXT, (void *)nContext);
  436.     if(ccode < 0)
  437.     {
  438.         HandleCcode(hDlg, ccode, "NWDSGetContext");
  439.         return(ccode);
  440.     }
  441.     return(FALSE);
  442. }
  443.  
  444.  
  445.  
  446. /***************************************************************************
  447. **  Reads all objects listed under the current container and fills in the
  448. **    list box on the main windows with the names of all of the objects.
  449. */
  450. long RefreshObjects(HWND hwnd)
  451. {
  452.     NWDSCCODE         ccode;
  453.     NWDS_ITERATION        iterHandle = -1L;
  454.     NWDS_BUFFER                *outBuf;
  455.     char                            objectName[MAX_DN_CHARS];
  456.     NWOBJECT_INFO            objectInfo;
  457.     NWCOUNT                        objCount;
  458.     NWCOUNT                        attrCount;
  459.     NWCOUNT                        counter=0;
  460.  
  461.     SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_RESETCONTENT, 0, 0);
  462.     SendDlgItemMessage(hwnd, IDC_ATTRIBUTES, LB_RESETCONTENT, 0, 0);
  463.     SetDlgItemText(hwnd, IDC_VALUES , "");
  464.  
  465.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  466.     if(ccode < 0)
  467.     {
  468.         HandleCcode(hwnd, ccode, "NWDSAllocBuf");
  469.         return 1;
  470.     }
  471.     do
  472.     {
  473.         /*  "" is being passing in as the object Name because to read
  474.                 all of the objects in the current context.*/
  475.  
  476.         ccode = NWDSList(gContext,     /* Context Handle        (IN) */
  477.                                     "",                      /* Object Name            (IN) */
  478.                                     &iterHandle,     /* Iteration Handle          (OUT)*/
  479.                                     outBuf);          /* Buffer to be filled     (OUT)*/
  480.         if(ccode < 0)
  481.         {
  482.             HandleCcode(hwnd, ccode, "NWDSList");
  483.             NWDSFreeBuf(outBuf);
  484.             return 1;
  485.         }
  486.         ccode = NWDSGetObjectCount(gContext,        /* Context Handle         (IN) */
  487.                                     outBuf,                                        /* Buffer full of info     (IN) */
  488.                                     &objCount);                                /* var for # of objects    (OUT)*/
  489.         if(ccode < 0)
  490.         {
  491.             HandleCcode(hwnd, ccode, "NWDSGetObjectCount");
  492.             NWDSFreeBuf(outBuf);
  493.             return 1;
  494.         }
  495.         for(counter=0; counter<objCount; counter++)
  496.         {
  497.             ccode = NWDSGetObjectName(gContext,        /* Context Handle         (IN)    */
  498.                                     outBuf,                                      /* Buffer with info    (IN)*/
  499.                                     objectName,                             /* object name             (OUT)*/
  500.                                     &attrCount,                             /* # of attributes     (OUT)*/
  501.                                     &objectInfo);                            /* Object Info             (OUT)*/
  502.             if(ccode < 0)
  503.             {
  504.                 HandleCcode(hwnd, ccode, "NWDSGetObjectName");
  505.                 NWDSFreeBuf(outBuf);
  506.                 return 1;
  507.             }
  508.             SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_ADDSTRING, 0,
  509.                             (LONG) (LPSTR) objectName);
  510.         }
  511.     }while(iterHandle != -1L);
  512.     SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_ADDSTRING, 0,
  513.                 (LONG) (LPSTR) ".");
  514.     NWDSFreeBuf(outBuf);
  515.     return 0;
  516. }
  517.  
  518.  
  519.  
  520. /***************************************************************************
  521. **  Reads all of the Attributes for the currently selected object in the
  522. **    main windows.  Then fills the names of the attributes into the list
  523. **    of attributes on the main window.  Note that only the Attributes that
  524. **    users have access to and that contain values will be shown.
  525. */
  526. long RefreshAttributes(HWND hwnd)
  527. {
  528.     NWDS_BUFFER                *outBuf;
  529.     NWDS_ITERATION        iterationHandle = -1L;
  530.     NWDSCCODE                    ccode;
  531.     char                            attrName[MAX_DN_CHARS];
  532.     char                            objectName[MAX_DN_CHARS];
  533.     NWCOUNT                        attrCount;
  534.     int                                i;
  535.     NWSYNTAX_ID                syntax;
  536.     NWCOUNT                        valCount;
  537.     WORD                            n;
  538.  
  539.     n = (WORD) SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_GETCURSEL, 0, 0L);
  540.     if(n == (WORD) LB_ERR)
  541.     {
  542.         MessageBox(hwnd, "Error", "No Object Selected!", MB_OK);
  543.         return 1;
  544.     }
  545.     SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_GETTEXT, n,
  546.                         (LONG) (LPSTR) objectName);
  547.     if(!strcmp(objectName, "."))
  548.     {
  549.         strcat(objectName, nContext);
  550.     }
  551.     SendDlgItemMessage(hwnd, IDC_ATTRIBUTES, LB_RESETCONTENT, 0, 0);
  552.     SetDlgItemText(hwnd, IDC_VALUES , "");
  553.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  554.     if(ccode < 0)
  555.     {
  556.         HandleCcode(hwnd, ccode, "NWDSAllocBuf");
  557.         return 1;
  558.     }
  559.     do
  560.     {
  561.         ccode = NWDSRead(gContext,                    /* Context Handle  (IN)        */
  562.                                 objectName,            /* name of object  (IN)        */
  563.                                 DS_ATTRIBUTE_NAMES,        /* a #define         (IN)            */
  564.                                 TRUE,                            /* #define as 1 (IN)            */
  565.                                 NULL,                            /* Attribute names (IN)     */
  566.                                 &iterationHandle,            /* iteration Handle (OUT) */
  567.                                 outBuf);                  /* Output Buffer (OUT)         */
  568.         if(ccode < 0)
  569.         {
  570.             HandleCcode(hwnd, ccode, "NWDSRead");
  571.             NWDSFreeBuf(outBuf);
  572.             return 1;
  573.         }
  574.         ccode = NWDSGetAttrCount(gContext, outBuf, &attrCount);
  575.         if(ccode < 0)
  576.         {
  577.             HandleCcode(hwnd, ccode, "NWDSGetAttrCount");
  578.             NWDSFreeBuf(outBuf);
  579.             return 1;
  580.         }
  581.  
  582.         for(i = 0; i < attrCount; i++)
  583.         {
  584.             ccode = NWDSGetAttrName(gContext, outBuf, attrName, &valCount, &syntax);
  585.             if(ccode < 0)
  586.             {
  587.                 HandleCcode(hwnd, ccode, "NWDSGetAttrName");
  588.                 NWDSFreeBuf(outBuf);
  589.                 return 1;
  590.             }
  591.             SendDlgItemMessage(hwnd, IDC_ATTRIBUTES, LB_ADDSTRING, 0,
  592.                             (LONG) (LPSTR) attrName);
  593.         }
  594.     }
  595.     while(iterationHandle != -1L);
  596.     NWDSFreeBuf(outBuf);
  597.     return 0;
  598. }
  599.  
  600.  
  601.  
  602. /***************************************************************************
  603. **    Reads the value of the currently selected attribute from the main window.
  604. **    Then displays the value in the text box on the main window.
  605. */
  606. WORD UpdateValueListBox(HWND hwnd)
  607. {
  608.     NWDS_BUFFER                    *outBuf,*inBuf;
  609.     NWDS_ITERATION                iterationHandle;
  610.     NWDSCCODE                    ccode;
  611.     char                            attrName[MAX_DN_CHARS];
  612.     char                            objectName[MAX_DN_CHARS];
  613.     int                            j;
  614.     NWSIZE                        attrSize;
  615.     NWSYNTAX_ID                    syntax;
  616.     NWCOUNT                        valCount;
  617.     NWCOUNT                        totalAttrs;
  618.     char                            currAttr[MAX_DN_CHARS];
  619.     HANDLE                        htxtBuffer, htmpBuffer, hattrValue;
  620.     void                            *attrValue;
  621.     char                            *txtBuffer;
  622.     char                            *tmpBuffer;
  623.     char                            rightsstr[9];
  624.     struct date                    dt;
  625.     struct time                    tm;
  626.     WORD                            n;
  627.     int                              fHandle;
  628.  
  629.     SetDlgItemText(hwnd, IDC_VALUES, "");
  630.     n = (WORD) SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_GETCURSEL, 0, 0L);
  631.     SendDlgItemMessage(hwnd, IDC_OBJECTS, LB_GETTEXT, n,
  632.                         (LONG) (LPSTR) objectName);
  633.     if(!strcmp(objectName, "."))
  634.     {
  635.         strcat(objectName, nContext);
  636.     }
  637.     n = (WORD) SendDlgItemMessage(hwnd, IDC_ATTRIBUTES, LB_GETCURSEL, 0, 0L);
  638.     SendDlgItemMessage(hwnd, IDC_ATTRIBUTES, LB_GETTEXT, n,
  639.                         (LONG) (LPSTR) attrName);
  640.     strset(rightsstr, '\x0');
  641.     iterationHandle = -1L;
  642.  
  643.     if((htxtBuffer = GlobalAlloc(LHND, DEFAULT_MESSAGE_LEN))==NULL)
  644.     {
  645.         MessageBox(hwnd, "Could not Allocate Memory", "Error", MB_OK);
  646.         return 1;
  647.     }
  648.     if((htmpBuffer = GlobalAlloc(LHND, DEFAULT_MESSAGE_LEN))==NULL)
  649.     {
  650.         GlobalFree(htxtBuffer);
  651.         MessageBox(hwnd, "Could not Allocate Memory", "Error", MB_OK);
  652.         return 1;
  653.     }
  654.     (void *)txtBuffer = GlobalLock(htxtBuffer);
  655.     (void *)tmpBuffer = GlobalLock(htmpBuffer);
  656.  
  657.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &inBuf);
  658.     if(ccode < 0)
  659.     {
  660.         GlobalUnlock(htxtBuffer);
  661.         GlobalFree(htxtBuffer);
  662.         GlobalUnlock(htmpBuffer);
  663.         GlobalFree(htmpBuffer);
  664.         HandleCcode(hwnd, ccode, "NWDSAllocBuf");
  665.         return(ccode);
  666.     }
  667.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  668.     if(ccode < 0)
  669.     {
  670.             GlobalUnlock(htxtBuffer);
  671.             GlobalFree(htxtBuffer);
  672.             GlobalUnlock(htmpBuffer);
  673.             GlobalFree(htmpBuffer);
  674.             HandleCcode(hwnd, ccode, "NWDSAllocBuf");
  675.             NWDSFreeBuf(inBuf);
  676.             return(ccode);
  677.      }
  678.     ccode = NWDSInitBuf(gContext,DSV_READ,inBuf);
  679.     if(ccode <0)
  680.     {
  681.             HandleCcode(hwnd, ccode, "NWDSInitBuf");
  682.             GlobalUnlock(htxtBuffer);
  683.             GlobalFree(htxtBuffer);
  684.             GlobalUnlock(htmpBuffer);
  685.             GlobalFree(htmpBuffer);
  686.             NWDSFreeBuf(inBuf);
  687.             NWDSFreeBuf(outBuf);
  688.             return(ccode);
  689.     }
  690.     ccode = NWDSPutAttrName(gContext,inBuf,attrName);
  691.     if(ccode <0)
  692.     {
  693.             HandleCcode(hwnd, ccode, "NWDSPutAttrName");
  694.             GlobalUnlock(htxtBuffer);
  695.             GlobalFree(htxtBuffer);
  696.             GlobalUnlock(htmpBuffer);
  697.             GlobalFree(htmpBuffer);
  698.             NWDSFreeBuf(inBuf);
  699.             NWDSFreeBuf(outBuf);
  700.             return(ccode);
  701.     }
  702.     do
  703.     {
  704.         ccode = NWDSRead(gContext,                    /* Context Handle  (IN)        */
  705.                                 objectName,            /* name of object  (IN)        */
  706.                                 DS_ATTRIBUTE_VALUES,        /* a #define         (IN)            */
  707.                                 FALSE,                            /* #define as 1 (IN)            */
  708.                                 inBuf,                            /* Attribute names (IN)     */
  709.                                 &iterationHandle,            /* iteration Handle (OUT) */
  710.                                 outBuf);                  /* Output Buffer (OUT)         */
  711.         if(ccode < 0)
  712.         {
  713.                 HandleCcode(hwnd, ccode, "NWDSRead");
  714.                 GlobalUnlock(htxtBuffer);
  715.                 GlobalFree(htxtBuffer);
  716.                 GlobalUnlock(htmpBuffer);
  717.                 GlobalFree(htmpBuffer);
  718.                 NWDSFreeBuf(inBuf);
  719.                 NWDSFreeBuf(outBuf);
  720.                 return(ccode);
  721.         }
  722.         ccode = NWDSGetAttrCount(gContext, outBuf, &totalAttrs);
  723.         if(ccode < 0)
  724.         {
  725.                 HandleCcode(hwnd, ccode, "NWDSGetAttrCount");
  726.                 GlobalUnlock(htxtBuffer);
  727.                 GlobalFree(htxtBuffer);
  728.                 GlobalUnlock(htmpBuffer);
  729.                 GlobalFree(htmpBuffer);
  730.                 NWDSFreeBuf(inBuf);
  731.                 NWDSFreeBuf(outBuf);
  732.                 return(ccode);
  733.         }
  734.         if((NWCOUNT)0 == totalAttrs)
  735.         {
  736.                 GlobalUnlock(htxtBuffer);
  737.                 GlobalFree(htxtBuffer);
  738.                 GlobalUnlock(htmpBuffer);
  739.                 GlobalFree(htmpBuffer);
  740.                 NWDSFreeBuf(inBuf);
  741.                 NWDSFreeBuf(outBuf);
  742.                 return(TRUE);
  743.         }
  744.         else
  745.         {
  746.             ccode = NWDSGetAttrName(gContext, outBuf, currAttr, &valCount, &syntax);
  747.             if(ccode < 0)
  748.             {
  749.                     HandleCcode(hwnd, ccode, "NWDSGetAttrName");
  750.                     GlobalUnlock(htxtBuffer);
  751.                     GlobalFree(htxtBuffer);
  752.                     GlobalUnlock(htmpBuffer);
  753.                     GlobalFree(htmpBuffer);
  754.                     NWDSFreeBuf(inBuf);
  755.                     NWDSFreeBuf(outBuf);
  756.                     return(ccode);
  757.             }
  758.             for(j = 0; j < valCount; j++)
  759.             {
  760.  
  761.                 /*  Note that the attribute value size is computed each time a value
  762.                         is read.  Each attribute may have multiple values and each value
  763.                         may be a different size */
  764.  
  765.                 ccode = NWDSComputeAttrValSize(gContext, outBuf, syntax, &attrSize);
  766.                 if(ccode < 0)
  767.                 {
  768.                         HandleCcode(hwnd, ccode, "NWDSComputeAttrValSize");
  769.                         GlobalUnlock(htxtBuffer);
  770.                         GlobalFree(htxtBuffer);
  771.                         GlobalUnlock(htmpBuffer);
  772.                         GlobalFree(htmpBuffer);
  773.                         NWDSFreeBuf(inBuf);
  774.                         NWDSFreeBuf(outBuf);
  775.                         return(ccode);
  776.                 }
  777.                 if((hattrValue = LocalAlloc(LHND, (UINT) attrSize))==NULL)
  778.                 {
  779.                     GlobalUnlock(htxtBuffer);
  780.                     GlobalFree(htxtBuffer);
  781.                     GlobalUnlock(htmpBuffer);
  782.                     GlobalFree(htmpBuffer);
  783.                     NWDSFreeBuf(inBuf);
  784.                     NWDSFreeBuf(outBuf);
  785.                     return(ccode);
  786.                 }
  787.                 attrValue = LocalLock(hattrValue);
  788.                 ccode = NWDSGetAttrVal(gContext, outBuf, syntax, attrValue);
  789.                 if(ccode < 0)
  790.                     break;
  791.                 switch(syntax)                  /* for syntax reference see the        */
  792.                 {                               /* NDS Schema Specification                */
  793.                     case SYN_BACK_LINK    :
  794.                                         sprintf(tmpBuffer,"%lu\r\n%s\r\n",((Back_Link_T *)attrValue)->remoteID,((Back_Link_T *)attrValue)->objectName);
  795.                                         break;
  796.                     case SYN_BOOLEAN        :
  797.                                         sprintf(tmpBuffer,"%s\r\n", ((*((uint8 *)attrValue)) ? "TRUE" : "FALSE"));
  798.                                         break;
  799.                     case SYN_CI_LIST        :
  800.                                         sprintf(tmpBuffer,"%s\r\n", ((CI_List_T *)attrValue)->s);
  801.                                         break;
  802.                     case SYN_COUNTER        :
  803.                                         sprintf(tmpBuffer,"%lu\r\n", *((uint32 *)attrValue));
  804.                                         break;
  805.                     case SYN_CE_STRING     :                                /* All of these are strings */
  806.                     case SYN_CI_STRING    :                                /* and therefore are all    */
  807.                     case SYN_NU_STRING    :               /* printed the same way     */
  808.                     case SYN_PR_STRING    :
  809.                     case SYN_TEL_NUMBER    :
  810.                     case SYN_CLASS_NAME    :
  811.                     case SYN_DIST_NAME    :
  812.                                         sprintf(tmpBuffer,"%s\r\n",(char *)attrValue);
  813.                                         break;
  814.                     case SYN_EMAIL_ADDRESS :
  815.                                         sprintf(tmpBuffer,"%lu, %s\r\n", ((EMail_Address_T *)attrValue)->type, ((EMail_Address_T *)attrValue)->address);
  816.                                         break;
  817.                     case SYN_FAX_NUMBER    :
  818.                                         sprintf(tmpBuffer,"%s\r\n",((Fax_Number_T *)attrValue)->telephoneNumber);
  819.                                         break;
  820.                     case SYN_HOLD        :
  821.                                         sprintf(tmpBuffer,"%s, %lu\r\n",((Hold_T *)attrValue)->objectName,((Hold_T *)attrValue)->amount);
  822.                                         break;
  823.                     case SYN_INTEGER    :
  824.                     case SYN_INTERVAL    :
  825.                                         sprintf(tmpBuffer,"%lu\r\n",*((uint32 *)attrValue));
  826.                                         break;
  827.                     case SYN_NET_ADDRESS    :
  828.                                         sprintf(tmpBuffer,"Address Type:%lu\r\nAddress Length:%lu\r\nAddress:%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X\r\n", ((Net_Address_T *)attrValue)->addressType,((Net_Address_T *)attrValue)->addressLength,((Net_Address_T *)attrValue)->address[0],((Net_Address_T *)attrValue)->address[1],((Net_Address_T *)attrValue)->address[2],((Net_Address_T *)attrValue)->address[3],((Net_Address_T *)attrValue)->address[4],((Net_Address_T *)attrValue)->address[5],((Net_Address_T *)attrValue)->address[6],((Net_Address_T *)attrValue)->address[7],((Net_Address_T *)attrValue)->address[8],((Net_Address_T *)attrValue)->address[9]);
  829.                                         break;
  830.                     case SYN_OBJECT_ACL    :
  831.                                         DecodeRights(((Object_ACL_T *)attrValue)->protectedAttrName, rightsstr, ((Object_ACL_T *)attrValue)->privileges);
  832.                                         sprintf(tmpBuffer,"%s %s %s\r\n",((Object_ACL_T *)attrValue)->protectedAttrName,rightsstr,((Object_ACL_T *)attrValue)->subjectName);
  833.                                         break;
  834.                     case SYN_OCTET_LIST :
  835.                                         sprintf(tmpBuffer,"Because the syntax SYN_OCTET_LIST is a linked list\r\nit is not shown here\r\n");
  836.                                         break;
  837.                     case SYN_OCTET_STRING :
  838.                                         sprintf(tmpBuffer,"Length: 0x%x\r\nData: 0x%x\r\n",((Octet_String_T *)attrValue)->length, (uint8 *)((Octet_String_T *)attrValue)->data);
  839.                                         break;
  840.                     case SYN_PATH    :
  841.                                         sprintf(tmpBuffer,"Name Space Type: %lu\r\n%s:%s\r\n",((Path_T *)attrValue)->nameSpaceType,((Path_T *)attrValue)->volumeName,((Path_T *)attrValue)->path);
  842.                                         break;
  843.                     case SYN_PO_ADDRESS :
  844.                                         sprintf(tmpBuffer,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n",((char **)attrValue)[0],((char **)attrValue)[1],((char **)attrValue)[2],((char **)attrValue)[3],((char **)attrValue)[4],((char **)attrValue)[5]);
  845.                                         break;
  846.                     case SYN_REPLICA_POINTER    :
  847.                                         sprintf(tmpBuffer,"serverName: %s\r\nreplicaType: %lu\r\nreplicaNumber: %u\r\ncount: %lu\r\nReplica_Pointer_T.Net_Address_T not shown\r\n", ((Replica_Pointer_T *)attrValue)->serverName,((Replica_Pointer_T *)attrValue)->replicaType,((Replica_Pointer_T *)attrValue)->replicaNumber,((Replica_Pointer_T *)attrValue)->count);
  848.                                         break;
  849.                     case SYN_STREAM :
  850.                                         ccode = NWDSOpenStream(gContext, objectName, currAttr, (NWDS_FLAGS)1, &fHandle);
  851.                                         if(!ccode)
  852.                                             _lread(fHandle, (void *)tmpBuffer, DEFAULT_MESSAGE_LEN);
  853.                                         else
  854.                                         {
  855.                                             sprintf(tmpBuffer,"NWDSOpenStream returned: %d",ccode);
  856.                                             MessageBox(hwnd, tmpBuffer, "View Attributes Error", MB_OK);
  857.                                         }
  858.                                         close(fHandle);
  859.                                         break;
  860.                     case SYN_TIME :
  861.                                         unixtodos(*((uint32 *)attrValue), &dt, &tm);
  862.                                         sprintf(tmpBuffer,"%d-%d-%d  %d:%d:%d\r\n", dt.da_mon, dt.da_day, dt.da_year, tm.ti_hour, tm.ti_min, tm.ti_sec);
  863.                                         break;
  864.                     case SYN_TIMESTAMP :
  865.                                         unixtodos(((NWDS_TimeStamp_T *)attrValue)->wholeSeconds, &dt, &tm);
  866.                                         sprintf(tmpBuffer,"%d-%d-%d  %d:%d:%d\r\n%lu\r\n", dt.da_mon, dt.da_day, dt.da_year, tm.ti_hour, tm.ti_min, tm.ti_sec, ((NWDS_TimeStamp_T *)attrValue)->eventID);
  867.                                         break;
  868.                     case SYN_TYPED_NAME :
  869.                                         sprintf(tmpBuffer,"0x%x, 0x%x, 0x%x\r\n", ((Typed_Name_T *)attrName)->objectName, ((Typed_Name_T *)attrName)->level, ((Typed_Name_T *)attrName)->interval);
  870.                                         break;
  871.                     default                :
  872.                                         sprintf(tmpBuffer,"Unrecognized Sytax\r\n");
  873.                                         break;
  874.                 }
  875.                 if(!((strlen(txtBuffer)) + (strlen(txtBuffer)) > DEFAULT_MESSAGE_LEN))
  876.                     strcat(txtBuffer,tmpBuffer);
  877.                 else
  878.                 {
  879.                     MessageBox(hwnd, "The Attribute you are reading holds more information\nthan is displayed but cannot be shown here.", "Memory Limit Reached", MB_OK);
  880.                     j= (int) valCount;
  881.                     iterationHandle = -1L;
  882.                 }
  883.                 SetDlgItemText(hwnd, IDC_VALUES, txtBuffer);
  884.                 LocalUnlock(hattrValue);
  885.                 LocalFree(hattrValue);
  886.             }
  887.         }
  888.     }
  889.     while(iterationHandle != -1L);
  890.     GlobalUnlock(htxtBuffer);
  891.     GlobalFree(htxtBuffer);
  892.     GlobalUnlock(htmpBuffer);
  893.     GlobalFree(htmpBuffer);
  894.     NWDSFreeBuf(inBuf);
  895.     NWDSFreeBuf(outBuf);
  896.     return 0;
  897. }
  898.  
  899.  
  900.  
  901. /***************************************************************************
  902. **    This procedure takes a list of rights (normally from an ACL) and
  903. **    translates then from the variable "privs" to a text format that is
  904. **    common to most network utilities.
  905. */
  906. void DecodeRights(char *attrName, char *rightsstring, NWDS_PRIVILEGES    privs)
  907. {
  908.     strset(rightsstring, '\x0');
  909.     strcat(rightsstring, "[");
  910.     if(!strcmp(attrName, "[Entry Rights]"))
  911.     {
  912.         if(privs & 0x01)                            /* DS_ENTRY_BROWSE */
  913.             strcat(rightsstring, "B");
  914.         if(privs & 0x02)                      /* DS_ENTRY_ADD */
  915.             strcat(rightsstring, "A");
  916.         if(privs & 0x04)                      /* DS_ENTRY_DELETE */
  917.             strcat(rightsstring, "D");
  918.         if(privs & 0x08)                      /* DS_ENTRY_RENAME */
  919.             strcat(rightsstring, "R");
  920.         if(privs & 0x10)                      /* DS_ENTRY_SUPERVISOR */
  921.             strcat(rightsstring, "S");
  922.     }
  923.     else
  924.     {
  925.         if(!strcmp(attrName, "[SMS Rights]"))
  926.         {
  927.             if(privs & 0x01)                        /* DS_SMS_SCAN */
  928.                 strcat(rightsstring, "S");
  929.             if(privs & 0x02)                        /* DS_SMS_BACKUP */
  930.                 strcat(rightsstring, "B");
  931.             if(privs & 0x04)                        /* DS_SMS_RESTORE */
  932.                 strcat(rightsstring, "R");
  933.             if(privs & 0x08)                        /* DS_SMS_RENAME */
  934.                 strcat(rightsstring, "C");
  935.             if(privs & 0x10)                        /* DS_SMS_DELETE */
  936.                 strcat(rightsstring, "D");
  937.             if(privs & 0x20)                        /* DS_SMS_ADMIN */
  938.                 strcat(rightsstring, "A");
  939.         }
  940.         else     /* Attribute Rights which applies to all others */
  941.         {
  942.             if(privs & 0x01)                        /* DS_ATTR_COMPARE */
  943.                 strcat(rightsstring, "C");
  944.             if(privs & 0x02)                        /* DS_ATTR_READ */
  945.                 strcat(rightsstring, "R");
  946.             if(privs & 0x04)                        /* DS_ATTR_WRITE */
  947.                 strcat(rightsstring, "W");
  948.             if(privs & 0x08)                        /* DS_ATTR_SELF */
  949.                 strcat(rightsstring, "A");
  950.             if(privs & 0x20)                        /* DS_ATTR_SUPERVISOR */
  951.                 strcat(rightsstring, "S");
  952.         }
  953.     }
  954.     strcat(rightsstring,"]\x0");
  955. }
  956.  
  957.  
  958.  
  959. /***************************************************************************
  960. **  This creates a process to handle an About dialog window and then creates
  961. **    the dialog.  Used here to change the context.
  962. */
  963. WORD ShowAboutDialog(HWND hDlg)
  964. {
  965.     static FARPROC lpfnAboutDlgProc;
  966.     lpfnAboutDlgProc = MakeProcInstance((FARPROC)AboutDlgProc, hInst);
  967.     DialogBox(hInst, "About", GetActiveWindow(), lpfnAboutDlgProc);
  968.     FreeProcInstance(lpfnAboutDlgProc);
  969.  return FALSE;
  970. }
  971.  
  972.  
  973.  
  974. /***************************************************************************
  975. **  This process handles all messages sent to the popup About dialog.
  976. */
  977. BOOL CALLBACK AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
  978. {
  979.     char    aboutBox[1024];
  980.  
  981.     switch (message)
  982.     {
  983.         case WM_CLOSE:
  984.             EndDialog (hDlg, 0);
  985.             return TRUE;
  986.         case WM_INITDIALOG:
  987.             strcpy(aboutBox, "This program is a viewer for Novell Directory Services (NDS)");
  988.             strcat(aboutBox, "The objects and attributes shown may vary depending rights to NDS.");
  989.             strcat(aboutBox, "Only attributes containing values are shown with this program.");
  990.             strcat(aboutBox, "\r\n\r\nDISCLAIMER\r\n\r\n");
  991.             strcat(aboutBox, "Novell, Inc. makes no representations or warranties with respect to ");
  992.             strcat(aboutBox, "any NetWare software, and specifically disclaims any express or ");
  993.             strcat(aboutBox, "implied warranties of merchantability, title, or fitness for a ");
  994.             strcat(aboutBox, "particular purpose.");
  995.             strcat(aboutBox, "\r\n\r\nDistribution of any NetWare software is forbidden without the ");
  996.             strcat(aboutBox, "express written consent of Novell, Inc.  Further, Novell reserves ");
  997.             strcat(aboutBox, "the right to discontinue distribution of any NetWare software. ");
  998.             strcat(aboutBox, "\r\n\r\nNovell is not responsible for lost profits or revenue, loss of use ");
  999.             strcat(aboutBox, "of the software, loss of data, costs of re-creating lost data, the ");
  1000.             strcat(aboutBox, "cost of any substitute equipment or program, or claims by any party ");
  1001.             strcat(aboutBox, "other than you.  Novell strongly recommends a backup be made before ");
  1002.             strcat(aboutBox, "any software is installed.   Technical support for this software ");
  1003.             strcat(aboutBox, "may be provided at the discretion of Novell. ");
  1004.             SetDlgItemText(hDlg, IDC_ABOUTBOX, aboutBox);
  1005.             return TRUE;
  1006.         case WM_COMMAND:
  1007.             switch (wParam)
  1008.             {
  1009.                 case IDC_ABOUTOK:
  1010.                     EndDialog (hDlg, 0);
  1011.                     return TRUE;
  1012.             }
  1013.             break;
  1014.     }
  1015.     return FALSE;
  1016. }
  1017.  
  1018.