|
|
1.1 root 1: /****************************************************************************\
2: *
1.1.1.2 ! root 3: * Microsoft Developer Support
! 4: * Copyright (c) 1992 Microsoft Corporation
! 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
121: * MAX_NUMBER_OF_RESOURCES_TO_ENUM had to be 2200 to see 3 or 4 sharable disk
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.2 ! root 128: #define MAX_NUMBER_OF_RESOURCES_TO_ENUM 28200
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: {
282: #define RESOURCE_BUF_ENTRIES 500
283: NETRESOURCE ResourceBuffer[RESOURCE_BUF_ENTRIES]; // about 13K for 500
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
402: * level NT Lan Man container, the second clause shows how to
403: * include in the filter a domain name, and the third and fourth
404: * clauses show how to include any servers whose names start with
405: * particular characters
406: *
407: \****************************************************************/
408:
409: if (!( (0==strncmp("NT Lan Man",ResourceBuffer[i].lpRemoteName,10))
1.1.1.2 ! root 410: ||(0==strncmp("pnt3191b",ResourceBuffer[i].lpRemoteName,8))
1.1 root 411: ||(0==strncmp("\\\\BR",ResourceBuffer[i].lpRemoteName,4))
1.1.1.2 ! root 412: ||(0==strncmp("\\\\BA",ResourceBuffer[i].lpRemoteName,4))))
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;
463: UCHAR ucPassword[] = "";
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;
516: UCHAR ucPassword[] = "";
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.