Annotation of q_a/samples/winnet/winnet.c, revision 1.1.1.3

1.1       root        1: /****************************************************************************\
                      2: *
1.1.1.2   root        3: *               Microsoft Developer Support
1.1.1.3 ! root        4: *               Copyright (c) 1992, 1993 Microsoft Corporation
1.1.1.2   root        5: *
1.1       root        6: * MODULE:       winnet.c
                      7: *
                      8: * PURPOSE:      Demonstrate the WNetXXX Win32 api(s) (10 of the 11 - all but
                      9: *                 WNetConnectionDialog are demonstrated)
                     10: *
                     11: * TO RUN:       Ensure 1 or more network disk shares can be used by the
                     12: *                 machine/user-id you run winnet on, and that these 1 or more
                     13: *                 network disk shares aren't already connected to the
                     14: *                 machine/user-id you run winnet on.  These net shares must
                     15: *                 not require a password
                     16: *
                     17: *               IMPORTANT:  Ensure W: is not in use when you type "WINNET"
                     18: *
                     19: * OVERALL APPROACH: Find a connectable disk resource on the network, connect
                     20: *                 to it, and disconnect
                     21: *
                     22: *               The first time you run this sample, it's probably best to
                     23: *                 ensure there's a shared disk directory accessable to the
                     24: *                 machine on which you run this program, so you can see the
                     25: *                 success paths in this code exercised first.  Ensure this
                     26: *                 shared disk is NOT already connected
                     27: *
                     28: *               We recursively open containers returned by the EnumResources
                     29: *                 calls (recursively using OpenEnum), but will bail out of the
                     30: *                 recursion without fully exploring all containers and enum's
                     31: *                 if we hit the arbitrary limit placed on how many connectable
                     32: *                 disk resources we enter into our list.  Since there may
                     33: *                 possibly be many more enumerable resources on a net than
                     34: *                 there are connectable disk resources, we also place another
                     35: *                 arbitrary limit on the total number of resources we'll
                     36: *                 enumerate
                     37: *
                     38: *               Both limits can easily be removed or raised by anyone working
                     39: *                 with this sample code
                     40: *
                     41: *               After the container exploration is completed, we walk down the
                     42: *                 list of connectable disk resources, arbitrarily picking one
                     43: *                 to connect to and then disconnect from
                     44: *
                     45: * FUNCTIONS:  Open_Do_Close_1_Enum
                     46: *
                     47: *               Called by main with a NULL container to start the enumeration
                     48: *                 of the top-level container.  Called recursively from
                     49: *                 EnumResources
                     50: *
                     51: *             OpenEnum
                     52: *
                     53: *               Returns an enumeration handle by opening a container
                     54: *
                     55: *             EnumResources
                     56: *
                     57: *               Enumerates the connectable resources and containers, given an
                     58: *                 enumeration handle.  Recusively calls Open_Do_Close_1_Enum
                     59: *
                     60: *             AddGetGetCancel
                     61: *             AddGetGetCancel2
                     62: *
                     63: *               Identical logic in both functions adds a connection, gets the
                     64: *                 user for the connection, gets information about the
                     65: *                 connection and then cancels the connection.  The difference
                     66: *                 is that AddGetGetCancel2 uses the new Win32 forms of the Add
                     67: *                 and Cancel api's
                     68: *
                     69: *             PrintAPIError
                     70: *
                     71: *               Simple routine to print error message info
                     72: *
                     73: * GLOBAL VARS:
                     74: *             ConnectablesList
                     75: *
                     76: *               List of disk resources we can connect to.  Filled in while
                     77: *                 enumeration resources, walked after all enumeration is
                     78: *                 complete
                     79: *
                     80: *             dwResourcesEnumedSoFar
                     81: *
                     82: *               Counter of resources enumerated so far, includes count of both
                     83: *                 disk resources and containers enumerated.  If many
                     84: *                 containers are enumerated compared to disk resources, this
                     85: *                 counter will limit the search.  If many disk resources are
                     86: *                 found compared to containers, the size of ConnectablesList
                     87: *                 will limit the search
                     88: *
                     89: *             dwDiskListI
                     90: *
                     91: *               Index into ConnectablesList.  At all times, except when adding
                     92: *                 a list entry, dwDiskListI is 1 greater than the number of
                     93: *                 entries we have entered into ConnectablesList
                     94: *
                     95: \****************************************************************************/
                     96: 
                     97: 
                     98: /****************************************************************************\
                     99: *  INCLUDES, DEFINES, TYPEDEFS
                    100: \****************************************************************************/
                    101: #define STRICT
                    102: #include <windows.h>
                    103: #include <stdio.h>
                    104: #include <string.h>
                    105: #include <stdlib.h>
                    106: #include <winnetwk.h>
                    107: 
                    108: #define PERR(api) printf("%s: Error %d from %s on line %d\n",  \
                    109:     __FILE__, GetLastError(), api, __LINE__);
                    110: #define PMSG(msg) printf("%s line %d: %s\n",  \
                    111:     __FILE__, __LINE__, msg);
                    112: 
                    113: #define PrintAppStyleAPIError(ApiTxt,MsgTxt) {                 \
                    114:   PrintAPIError( #ApiTxt , #MsgTxt , __LINE__ , __FILE__ ); \
                    115:   }
                    116: 
                    117: 
                    118: /****************************************************************************\
                    119: *
                    120: * These next two search limits are completely tunable.  On one net
1.1.1.3 ! root      121: *   MAX_NUMBER_OF_RESOURCES_TO_ENUM had to be large to see 3 or 4 sharable disk
1.1       root      122: *   resources.  This could vary widely depending on the number of servers on
                    123: *   the net that have no shares up
                    124: *
                    125: \****************************************************************************/
                    126: 
                    127: #define MAX_NUMBER_OF_DISK_RESOURCES_TO_LIST 3
1.1.1.3 ! root      128: #define MAX_NUMBER_OF_RESOURCES_TO_ENUM      480000
1.1       root      129: 
                    130: #define LOCAL_DEVICE_NAME                    "W:"
                    131: #define WHICH_TO_USE_FROM_LIST               0
                    132: 
                    133: typedef struct _DISK_RESOURCES_CONNECTABLE
                    134: {
                    135:   LPTSTR lpRemoteName;
                    136:   LPTSTR lpComment;
                    137:   LPTSTR lpProvider;
                    138: } DISK_RESOURCES_CONNECTABLE, *LPDISK_RESOURCES_CONNECTABLE;
                    139: 
                    140: /****************************************************************************\
                    141: * GLOBAL VARIABLES
                    142: \****************************************************************************/
                    143: 
                    144: DISK_RESOURCES_CONNECTABLE
                    145:                ConnectablesList[MAX_NUMBER_OF_DISK_RESOURCES_TO_LIST];
                    146: DWORD    dwResourcesEnumedSoFar = 0;
                    147: DWORD    dwDiskListI            = 0;
                    148: 
                    149: /****************************************************************************\
                    150: * FUNCTION PROTOTYPES
                    151: \****************************************************************************/
                    152: 
                    153: VOID   Open_Do_Close_1_Enum(LPNETRESOURCE lpNetContainerToOpen);
                    154: HANDLE OpenEnum            (LPNETRESOURCE lpNetContainerToOpen);
                    155: UINT   EnumResources(HANDLE hNetEnum);
                    156: VOID   AddGetGetCancel(VOID);
                    157: VOID   AddGetGetCancel2(VOID);
                    158: VOID   PrintAPIError(LPTSTR ApiTxt,
                    159:                      LPTSTR MsgTxt,
                    160:                      UINT   Line,
                    161:                      LPTSTR File);
                    162: 
                    163: /****************************************************************************\
                    164: *
                    165: * FUNCTION: Main
                    166: *
                    167: \****************************************************************************/
                    168: 
                    169: UINT main(UINT argc, char *argv[])
                    170: {
                    171:   UNREFERENCED_PARAMETER(argv[1]);
                    172: 
                    173:   if (argc > 1)
                    174:   { printf("\nTo run type 'winnet', with no parameters\n");
                    175:     printf("\n  IMPORTANT: Ensure W: is not in use when you type WINNET\n");
                    176:     return(1);
                    177:   }
                    178: 
                    179:   /**************************************************************************\
                    180:   *
                    181:   * Pass NULL as container argument to get top level container.  This call
                    182:   *   starts the recursive exploration of the top level network resource
                    183:   *   container
                    184:   *
                    185:   \**************************************************************************/
                    186: 
                    187:   Open_Do_Close_1_Enum(NULL);
                    188: 
                    189:   /**************************************************************************\
                    190:   *
                    191:   * We now have a list of connectable resources in our table, but some error
                    192:   *   conditions may have caused the list to be 0 length
                    193:   *
                    194:   \**************************************************************************/
                    195: 
                    196:   if (0<dwDiskListI)
                    197:   { AddGetGetCancel();
                    198:     AddGetGetCancel2();
                    199:   }
                    200:   else
                    201:   { printf("\nError: enumerated 0 connectable disk resources!\n");
                    202:   }
                    203: 
                    204:   /**************************************************************************\
                    205:   *
                    206:   * Free the list of connectable resources, zero length or not
                    207:   *
                    208:   \**************************************************************************/
                    209: 
                    210:   { DWORD i;
                    211:     for (i=0; i<dwDiskListI; i++)
                    212:     {
                    213:       free(ConnectablesList[i].lpRemoteName);
                    214:       free(ConnectablesList[i].lpComment   );
                    215:       free(ConnectablesList[i].lpProvider  );
                    216:     }
                    217:   }
                    218: 
                    219:   return(0);
                    220: }
                    221: 
                    222: /****************************************************************************\
                    223: *
                    224: * FUNCTION: Open_Do_Close_1_Enum
                    225: *
                    226: * COMMENTS: There's little reason this is in a separate function in this
                    227: *             sample other than the code is used in two places, so putting it
                    228: *             in a separate function saves repetition in the source code
                    229: *
                    230: \****************************************************************************/
                    231: 
                    232: VOID Open_Do_Close_1_Enum(LPNETRESOURCE lpNetContainerToOpen)
                    233: {
                    234:   HANDLE hNetEnum;
                    235: 
                    236:   hNetEnum = OpenEnum(lpNetContainerToOpen);
                    237: 
                    238:   if (!hNetEnum)
                    239:     return;
                    240: 
                    241:   if (!EnumResources(hNetEnum))
                    242:     return;
                    243: 
                    244:   if (NO_ERROR != WNetCloseEnum(hNetEnum))
                    245:   { PERR("WNetCloseEnum");
                    246:     return;
                    247:   }
                    248: }
                    249: 
                    250: /****************************************************************************\
                    251: *
                    252: * FUNCTION: OpenEnum
                    253: *
                    254: \****************************************************************************/
                    255: 
                    256: HANDLE OpenEnum(LPNETRESOURCE lpNetContainerToOpen)
                    257: {
                    258:   HANDLE hNetEnum;
                    259: 
                    260:   if (NO_ERROR != WNetOpenEnum(RESOURCE_GLOBALNET,
                    261:                                RESOURCETYPE_DISK,
                    262:                                (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER),
                    263:                                lpNetContainerToOpen,
                    264:                                (LPHANDLE)&hNetEnum))
                    265:   { if (GetLastError() != NO_ERROR)
                    266:     { PrintAppStyleAPIError(WNetOpenEnum,"OpenEnum");
                    267:       return(NULL);
                    268:     }
                    269:   }
                    270: 
                    271:   return(hNetEnum);
                    272: }
                    273: 
                    274: /****************************************************************************\
                    275: *
                    276: * FUNCTION: EnumResources
                    277: *
                    278: \****************************************************************************/
                    279: 
                    280: UINT EnumResources(HANDLE hNetEnum)
                    281: {
1.1.1.3 ! root      282:   #define                    RESOURCE_BUF_ENTRIES 5000
        !           283:   NETRESOURCE ResourceBuffer[RESOURCE_BUF_ENTRIES];
1.1       root      284:   DWORD       dwSzResourceBuf;
                    285:   DWORD       dwEntriesToGet;
                    286: 
                    287:   /**************************************************************************\
                    288:   *
                    289:   * It's possible that not all entries will fit in a RESOURCE_BUF_ENTRIES slot
                    290:   *   buffer, so we call WNetEnumResource in a loop, asking for
                    291:   *   RESOURCE_BUF_ENTRIES at a time, and continuing to call WNetEnumResource
                    292:   *   until it returns no more entries
                    293:   *
                    294:   \**************************************************************************/
                    295: 
                    296:   for (;;)
                    297:   {
                    298:     dwSzResourceBuf = sizeof(ResourceBuffer);
                    299:     dwEntriesToGet  = RESOURCE_BUF_ENTRIES;
                    300: 
                    301:     printf("Getting %d entries\n",dwEntriesToGet);
                    302: 
                    303:     if (NO_ERROR != WNetEnumResource(hNetEnum,
                    304:                                      (LPDWORD)&dwEntriesToGet,
                    305:                                      (LPVOID)ResourceBuffer,
                    306:                                      (LPDWORD)&dwSzResourceBuf))
                    307:     { switch (GetLastError())
                    308:       { case NO_ERROR            :
                    309:           // Drop out of the switch, walk the buffer
                    310:           break;
                    311:         case ERROR_NO_MORE_ITEMS :
                    312:           // Return with 0 code because this only happens when we got
                    313:           //   RESOURCE_BUF_ENTRIES entries on the previous call to
                    314:           //   WNetEnumResource, and there were coincidentally exactly
                    315:           //   RESOURCE_BUF_ENTRIES entries total in the enum at the time of
                    316:           //   that previous call
                    317:           return(0);
                    318:         default                  :
                    319:           PrintAppStyleAPIError(WNetEnumResource,"EnumResources");
                    320:           return(1);
                    321:       }
                    322:     }
                    323: 
                    324:     /************************************************************************\
                    325:     *
                    326:     * Walk the returned buffer.  Now dwEntriesToGet has been set by the api
                    327:     *   call to be the number of entries actually returned
                    328:     *
                    329:     \************************************************************************/
                    330: 
                    331:     {
                    332:       DWORD i;
                    333: 
                    334:       printf("Got %d entries\n",dwEntriesToGet);
                    335: 
                    336:       for (i=0; i<dwEntriesToGet; i++)
                    337:       {
                    338:         printf("\nResourceBuffer[%d].dwScope      = 0x%x \n",i,
                    339:                 ResourceBuffer[i].dwScope);
                    340:         printf("ResourceBuffer[%d].dwType       = 0x%x \n",i,
                    341:                 ResourceBuffer[i].dwType);
                    342:         printf("ResourceBuffer[%d].dwUsage      = 0x%x \n",i,
                    343:                 ResourceBuffer[i].dwUsage);
                    344:         printf("ResourceBuffer[%d].lpLocalName  = %s   \n",i,
                    345:                 ResourceBuffer[i].lpLocalName);
                    346:         printf("ResourceBuffer[%d].lpRemoteName = %s   \n",i,
                    347:                 ResourceBuffer[i].lpRemoteName);
                    348:         printf("ResourceBuffer[%d].lpComment    = %s   \n",i,
                    349:                 ResourceBuffer[i].lpComment);
                    350:         printf("ResourceBuffer[%d].lpProvider   = %s   \n",i,
                    351:                 ResourceBuffer[i].lpProvider);
                    352: 
                    353:         dwResourcesEnumedSoFar += dwEntriesToGet;
                    354: 
                    355:         printf("dwResourcesEnumedSoFar = %d \n",dwResourcesEnumedSoFar);
                    356: 
                    357:         if (dwDiskListI >= MAX_NUMBER_OF_DISK_RESOURCES_TO_LIST)
                    358:           return(0);  // List full, stop enumerating
                    359: 
                    360:         switch (ResourceBuffer[i].dwUsage)
                    361:         { case RESOURCEUSAGE_CONNECTABLE :
                    362: 
                    363:             ConnectablesList      [dwDiskListI].lpRemoteName =
                    364:               malloc(1+strlen(ResourceBuffer[i].lpRemoteName));
                    365:             ConnectablesList      [dwDiskListI].lpComment    =
                    366:               malloc(1+strlen(ResourceBuffer[i].lpComment   ));
                    367:             ConnectablesList      [dwDiskListI].lpProvider   =
                    368:               malloc(1+strlen(ResourceBuffer[i].lpProvider  ));
                    369: 
                    370:             if ((NULL == ConnectablesList[dwDiskListI].lpRemoteName) ||
                    371:                 (NULL == ConnectablesList[dwDiskListI].lpComment   ) ||
                    372:                 (NULL == ConnectablesList[dwDiskListI].lpProvider  ))
                    373:               PERR("EnumResource - ran out of heap space");
                    374: 
                    375:             strcpy(ConnectablesList[dwDiskListI].lpRemoteName,
                    376:                                ResourceBuffer[i].lpRemoteName);
                    377:             strcpy(ConnectablesList[dwDiskListI].lpComment   ,
                    378:                                ResourceBuffer[i].lpComment   );
                    379:             strcpy(ConnectablesList[dwDiskListI].lpProvider  ,
                    380:                                ResourceBuffer[i].lpProvider  );
                    381: 
                    382:             dwDiskListI++;
                    383: 
                    384:             break;
                    385: 
                    386:           case  RESOURCEUSAGE_CONTAINER                           : // Regular container
                    387:           case (RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED) : // Top-level container
                    388: 
                    389:             /****************************************************************\
                    390:             *
                    391:             * This next test is here to filter out servers we don't wish to
                    392:             *   enumerate while running the sample.  A real app would be more
                    393:             *   likely to look at all servers, but for running a sample, it's
                    394:             *   worthwhile to think about which servers should actually be
                    395:             *   enumerated, to avoid annoying people who have other servers on
                    396:             *   the net they may not wish to be disturbed
                    397:             *
                    398:             * So, you may want to modify this test to filter out whatever
                    399:             *   servers make sense to filter out in your environment
                    400:             *
                    401:             * The first clause shows how to include in the filter the top
1.1.1.3 ! root      402:             *   level Windows NT network provider container, the second clause
        !           403:             *   shows how to include in the filter a domain name, and the
        !           404:             *   third and fourth clauses show how to include any servers whose
        !           405:             *   names start with particular characters
1.1       root      406:             *
                    407:             \****************************************************************/
                    408: 
1.1.1.3 ! root      409:             if (!(  (0==_strnicmp("Microsoft Windows Network",ResourceBuffer[i].lpRemoteName,25))
        !           410:                   ||(0==_strnicmp("DMAIN1",ResourceBuffer[i].lpRemoteName,6))
        !           411:                   ||(0==_strnicmp("\\\\BLUMPR2",ResourceBuffer[i].lpRemoteName,9))
        !           412:                   ||(0==_strnicmp("\\\\BLAMTR2",ResourceBuffer[i].lpRemoteName,9))))
1.1       root      413:               break;
                    414: 
                    415:             if (dwResourcesEnumedSoFar < MAX_NUMBER_OF_RESOURCES_TO_ENUM)
                    416:               Open_Do_Close_1_Enum(&ResourceBuffer[i]);
                    417: 
                    418:             break;
                    419: 
                    420:           case RESOURCEUSAGE_RESERVED    :   // Ignore these
                    421:             break;
                    422: 
                    423:           default                        :
1.1.1.2   root      424:           { UCHAR ucMsgBuf[1500];
1.1       root      425: 
1.1.1.2   root      426:             sprintf(ucMsgBuf,"WNetEnumResources bad .dwUsage value = 0x%X,\n",
                    427:               ResourceBuffer[i].dwUsage);
                    428:             PERR(ucMsgBuf);
                    429:             return(1);
                    430:           }
1.1       root      431:         }
                    432:       }
                    433:     }
                    434: 
                    435:     /************************************************************************\
                    436:     *
                    437:     * We have walked the returned buffer.  Since dwEntriesToGet has been set
                    438:     *   by the api call to be the number of entries actually returned, if how
                    439:     *   many were returned is less than what we asked for, return out of the
                    440:     *   loop because this enum is done
                    441:     *
                    442:     \************************************************************************/
                    443: 
                    444:     if (dwEntriesToGet < RESOURCE_BUF_ENTRIES)
                    445:       return(0);
                    446: 
                    447:   }
                    448:   PERR("WNetEnumResource - impossible to drop out of infinite loop");
                    449:   return(1);
                    450: }
                    451: 
                    452: /****************************************************************************\
                    453: *
                    454: * FUNCTION: AddGetGetCancel
                    455: *
                    456: * COMMENTS: Connects to first disk resource on our global list
                    457: *
                    458: \****************************************************************************/
                    459: 
                    460: VOID AddGetGetCancel(VOID)
                    461: {
                    462:   UCHAR ucLocalName[sizeof(LOCAL_DEVICE_NAME)+1] = LOCAL_DEVICE_NAME;
1.1.1.3 ! root      463:   UCHAR ucPassword[] = "Passw00";
1.1       root      464:   #define            SZ_BUF 1000
                    465:   UCHAR ucRemoteName[SZ_BUF];
                    466:   UCHAR ucUserName  [SZ_BUF];
                    467:   DWORD dwSzBuf    = SZ_BUF;
                    468: 
                    469:   if (NO_ERROR != WNetAddConnection(
                    470:                       ConnectablesList[WHICH_TO_USE_FROM_LIST].lpRemoteName,
                    471:                       (LPTSTR)ucPassword,(LPTSTR)ucLocalName))
                    472:   { PrintAppStyleAPIError(WNetAddConnection,"AddGetGetCancel");
                    473:     return;
                    474:   }
                    475: 
                    476:   dwSzBuf = SZ_BUF;
                    477: 
                    478:   if (NO_ERROR != WNetGetConnection((LPTSTR)ucLocalName,
                    479:                       (LPTSTR)ucRemoteName,(LPDWORD)&dwSzBuf))
                    480:   { PrintAppStyleAPIError(WNetGetConnection,"AddGetGetCancel");
                    481:     return;
                    482:   }
                    483: 
                    484:   dwSzBuf = SZ_BUF;
                    485: 
                    486:   if (NO_ERROR != WNetGetUser((LPTSTR)ucLocalName,
                    487:                       (LPTSTR)ucUserName,(LPDWORD)&dwSzBuf))
                    488:   { PrintAppStyleAPIError(WNetGetUser,"AddGetGetCancel");
                    489:     return;
                    490:   }
                    491: 
                    492:   printf("\nDisk resource AddGetGetCancel connected = [%s], User name logged on to that resource = [%s]\n",
                    493:           ucRemoteName,ucUserName);
                    494: 
                    495:   if (NO_ERROR != WNetCancelConnection((LPTSTR)ucLocalName,FALSE))
                    496:   { PrintAppStyleAPIError(WNetCancelConnection,"AddGetGetCancel");
                    497:     return;
                    498:   }
                    499: }
                    500: 
                    501: /****************************************************************************\
                    502: *
                    503: * FUNCTION: AddGetGetCancel2
                    504: *
                    505: * COMMENTS: If we had chosen to keep our list as a list of NetResource data
                    506: *             structures, using the new form of AddConnection2 would have been
                    507: *             easier to code.  As it is, declaring and filling in the
                    508: *             NetResource takes a few more lines
                    509: *
                    510: \****************************************************************************/
                    511: 
                    512: VOID AddGetGetCancel2(VOID)
                    513: {
                    514:   UCHAR ucLocalName[sizeof(LOCAL_DEVICE_NAME)+1] = LOCAL_DEVICE_NAME;
                    515:   NETRESOURCE ToConnect;
1.1.1.3 ! root      516:   UCHAR ucPassword[] = "Passw00";
1.1       root      517:   #define            SZ_BUF 1000
                    518:   UCHAR ucRemoteName[SZ_BUF];
                    519:   UCHAR ucUserName  [SZ_BUF] = "AUserName";
                    520:   DWORD dwSzBuf    = SZ_BUF;
                    521: 
                    522:   ToConnect.lpRemoteName =
                    523:     ConnectablesList[WHICH_TO_USE_FROM_LIST].lpRemoteName;
                    524:   ToConnect.lpLocalName  = ucLocalName;
                    525:   ToConnect.lpProvider   = NULL;
                    526:   ToConnect.dwType       = RESOURCETYPE_DISK;
                    527: 
                    528:   if (NO_ERROR != WNetAddConnection2(&ToConnect,(LPTSTR)ucPassword,
                    529:                       (LPTSTR)ucUserName,CONNECT_UPDATE_PROFILE))
                    530:   { PrintAppStyleAPIError(WNetAddConnection2,"AddGetGetCancel2");
                    531:     return;
                    532:   }
                    533: 
                    534:   dwSzBuf = SZ_BUF;
                    535: 
                    536:   if (NO_ERROR != WNetGetConnection((LPTSTR)ucLocalName,
                    537:                       (LPTSTR)ucRemoteName,(LPDWORD)&dwSzBuf))
                    538:   { PrintAppStyleAPIError(WNetGetConnection,"AddGetGetCancel2");
                    539:     return;
                    540:   }
                    541: 
                    542:   dwSzBuf = SZ_BUF;
                    543: 
                    544:   if (NO_ERROR != WNetGetUser((LPTSTR)ucLocalName,
                    545:                       (LPTSTR)ucUserName,(LPDWORD)&dwSzBuf))
                    546:   { PrintAppStyleAPIError(WNetGetUser,"AddGetGetCancel2");
                    547:     return;
                    548:   }
                    549: 
                    550:   printf("\nDisk resource AddGetGetCancel2 connected = [%s], User name logged on to that resource = [%s]\n",
                    551:           ucRemoteName,ucUserName);
                    552: 
                    553:   if (NO_ERROR != WNetCancelConnection2((LPTSTR)ucLocalName,
                    554:                       CONNECT_UPDATE_PROFILE,FALSE))
                    555:   { PrintAppStyleAPIError(WNetCancelConnection2,"AddGetGetCancel2");
                    556:     return;
                    557:   }
                    558: }
                    559: 
                    560: /****************************************************************************\
                    561: *
                    562: * FUNCTION: PrintAPIError
                    563: *
                    564: \****************************************************************************/
                    565: 
                    566: VOID   PrintAPIError(LPTSTR ApiTxt,
                    567:                      LPTSTR MsgTxt,
                    568:                      UINT   Line,
                    569:                      LPTSTR File)
                    570: { DWORD dwLastError;
                    571: 
                    572:   dwLastError = GetLastError();
                    573:   switch (dwLastError)
                    574:   { case        NO_ERROR                  :
                    575:       printf("\nNO_ERROR not expected (%s) line %d file %s",MsgTxt,Line,File);
                    576:       break;
                    577:     case        ERROR_EXTENDED_ERROR      :
                    578:       { LPDWORD lpdwErrorCode;
                    579: 
                    580:         #define          SZ_ERROR_BUF                  4000
                    581:         UCHAR ucErrorBuf[SZ_ERROR_BUF];
                    582:         #define                 SZ_PROVIDER_NAME_BUF   400
                    583:         UCHAR ucProviderNameBuf[SZ_PROVIDER_NAME_BUF];
                    584: 
                    585:         if (NO_ERROR != WNetGetLastError(lpdwErrorCode,
                    586:                                            (LPTSTR)ucErrorBuf,
                    587:                                             (DWORD)SZ_ERROR_BUF,
                    588:                                            (LPTSTR)ucProviderNameBuf,
                    589:                                             (DWORD)SZ_PROVIDER_NAME_BUF))
                    590:         { PERR("WNetGetLastError");
                    591:         }
                    592:         else
                    593:         {
                    594:           #define        szMsgBuf   SZ_ERROR_BUF * 2
                    595:           UCHAR ucMsgBuf[szMsgBuf];
                    596: 
                    597:           sprintf(ucMsgBuf,
                    598:             "WNetGetLastError code = %d, Msg=[%s], Provider =[%s] line %d file %s",
                    599:             lpdwErrorCode,ucErrorBuf,ucProviderNameBuf,Line,File);
                    600:           PERR(ucMsgBuf);
                    601:         }
                    602:       }
                    603:       break;
                    604:     case        ERROR_NOT_SUPPORTED       :
                    605:       printf("\nERROR_NOT_SUPPORTED (%s) line %d file %s",MsgTxt,Line,File);
                    606:       break;
                    607:     case        ERROR_UNEXP_NET_ERR       :
                    608:       printf("\nERROR_UNEXP_NET_ERR (%s) line %d file %s",MsgTxt,Line,File);
                    609:       break;
                    610:     case        ERROR_MORE_DATA           :
                    611:       printf("\nERROR_MORE_DATA (%s) line %d file %s",MsgTxt,Line,File);
                    612:       break;
                    613:     case        ERROR_INVALID_ADDRESS     :
                    614:       printf("\nERROR_INVALID_ADDRESS (%s) line %d file %s",MsgTxt,Line,File);
                    615:       break;
                    616:     case        ERROR_INVALID_PARAMETER   :
                    617:       printf("\nERROR_INVALID_PARAMETER (%s) line %d file %s",MsgTxt,Line,File);
                    618:       break;
                    619:     case        ERROR_INVALID_PASSWORD    :
                    620:       printf("\nERROR_INVALID_PASSWORD (%s) line %d file %s",MsgTxt,Line,File);
                    621:       break;
                    622:     case        ERROR_ACCESS_DENIED       :
                    623:       printf("\nERROR_ACCESS_DENIED (%s) line %d file %s",MsgTxt,Line,File);
                    624:       break;
                    625:     case        ERROR_BUSY                :
                    626:       printf("\nERROR_BUSY (%s) line %d file %s",MsgTxt,Line,File);
                    627:       break;
                    628:     case        ERROR_BAD_USERNAME        :
                    629:       printf("\nERROR_BAD_USERNAME (%s) line %d file %s",MsgTxt,Line,File);
                    630:       break;
                    631:     case        ERROR_NOT_ENOUGH_MEMORY   :
                    632:       printf("\nERROR_NOT_ENOUGH_MEMORY (%s) line %d file %s",MsgTxt,Line,File);
                    633:       break;
                    634:     case        ERROR_NO_NETWORK          :
                    635:       printf("\nERROR_NO_NETWORK (%s) line %d file %s",MsgTxt,Line,File);
                    636:       break;
                    637:     case        ERROR_NOT_CONNECTED       :
                    638:       printf("\nERROR_NOT_CONNECTED (%s) line %d file %s",MsgTxt,Line,File);
                    639:       break;
                    640:     case        ERROR_OPEN_FILES          :
                    641:       printf("\nERROR_OPEN_FILES (%s) line %d file %s",MsgTxt,Line,File);
                    642:       break;
                    643:     case        ERROR_DEVICE_IN_USE       :
                    644:       printf("\nERROR_DEVICE_IN_USE (%s) line %d file %s",MsgTxt,Line,File);
                    645:       break;
                    646:     case        ERROR_BAD_NET_NAME        :
                    647:       printf("\nERROR_BAD_NET_NAME (%s) line %d file %s",MsgTxt,Line,File);
                    648:       break;
                    649:     case        ERROR_BAD_DEVICE          :
                    650:       printf("\nERROR_BAD_DEVICE (%s) line %d file %s",MsgTxt,Line,File);
                    651:       break;
                    652:     case        ERROR_ALREADY_ASSIGNED    :
                    653:       printf("\nERROR_ALREADY_ASSIGNED (%s) line %d file %s",MsgTxt,Line,File);
                    654:       break;
                    655:     case        ERROR_GEN_FAILURE         :
                    656:       printf("\nERROR_GEN_FAILURE (%s) line %d file %s",MsgTxt,Line,File);
                    657:       break;
                    658:     case        ERROR_CONNECTION_UNAVAIL  :
                    659:       printf("\nERROR_CONNECTION_UNAVAIL (%s) line %d file %s",MsgTxt,Line,File);
                    660:       break;
                    661:     case        ERROR_NO_NET_OR_BAD_PATH  :
                    662:       printf("\nERROR_NO_NET_OR_BAD_PATH (%s) line %d file %s",MsgTxt,Line,File);
                    663:       break;
                    664:     case        ERROR_BAD_PROVIDER        :
                    665:       printf("\nERROR_BAD_PROVIDER (%s) line %d file %s",MsgTxt,Line,File);
                    666:       break;
                    667:     case        ERROR_CANNOT_OPEN_PROFILE :
                    668:       printf("\nERROR_CANNOT_OPEN_PROFILE (%s) line %d file %s",MsgTxt,Line,File);
                    669:       break;
                    670:     case        ERROR_BAD_PROFILE         :
                    671:       printf("\nERROR_BAD_PROFILE (%s) line %d file %s",MsgTxt,Line,File);
                    672:       break;
                    673:     case        ERROR_INVALID_HANDLE      :
                    674:       printf("\nERROR_INVALID_HANDLE (%s) line %d file %s",MsgTxt,Line,File);
                    675:       break;
                    676:     case        ERROR_NO_MORE_ITEMS       :
                    677:       printf("\nERROR_NO_MORE_ITEMS (%s) line %d file %s",MsgTxt,Line,File);
                    678:       break;
                    679:     case        ERROR_NOT_CONTAINER       :
                    680:       printf("\nERROR_NOT_CONTAINER (%s) line %d file %s",MsgTxt,Line,File);
                    681:       break;
                    682:     default                               :
                    683:       printf("\n%s - unexpected return code=%d (%s) line %d file %s",ApiTxt,dwLastError,MsgTxt,Line,File);
                    684:       break;
                    685:   }
                    686: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.