Win32OperatingSystem.st
changeset 15076 f4c814ed8258
parent 15039 aad511684e79
child 15169 0cf7770d6e58
child 18045 c0c600e0d3b3
--- a/Win32OperatingSystem.st	Mon Apr 08 12:47:05 2013 +0200
+++ b/Win32OperatingSystem.st	Wed Apr 10 10:04:37 2013 +0200
@@ -10,6 +10,8 @@
  other person.  No title to or ownership of the software is
  hereby transferred.
 "
+'From Smalltalk/X, Version:6.2.3.0 on 10-04-2013 at 09:59:01'                   !
+
 "{ Package: 'stx:libbasic' }"
 
 AbstractOperatingSystem subclass:#Win32OperatingSystem
@@ -135,6 +137,22 @@
 	privateIn:Win32OperatingSystem
 !
 
+Win32Handle subclass:#Win32NetworkResourceHandle
+	instanceVariableNames:''
+	classVariableNames:'ScopeMappingTable TypeMappingTable DisplayTypeMappingTable
+		UsageMappingTable'
+	poolDictionaries:''
+	privateIn:Win32OperatingSystem
+!
+
+Object subclass:#NetworkResource
+	instanceVariableNames:'scope type usage displayType remoteName localName provider
+		comment'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:Win32OperatingSystem::Win32NetworkResourceHandle
+!
+
 Win32Handle subclass:#Win32PrinterHandle
 	instanceVariableNames:''
 	classVariableNames:''
@@ -828,7 +846,6 @@
     "Modified: 7.1.1997 / 19:36:11 / stefan"
 ! !
 
-
 !Win32OperatingSystem class methodsFor:'OS signal constants'!
 
 sigABRT
@@ -7376,6 +7393,14 @@
     "Modified: / 03-08-2010 / 17:00:10 / cg"
 ! !
 
+!Win32OperatingSystem class methodsFor:'network resources'!
+
+networkResourceAccessor
+    "answer the Win32NetworkResourceHandle or nil if not supported"
+
+    ^ Win32NetworkResourceHandle
+! !
+
 !Win32OperatingSystem class methodsFor:'os queries'!
 
 executableFileExtensions
@@ -15447,6 +15472,620 @@
 %}.
 ! !
 
+!Win32OperatingSystem::Win32NetworkResourceHandle class methodsFor:'accessing - types'!
+
+displayTypeMappingTable
+    "answer a Dictionary containing displayTypes symbols to integer mapping and vice versa"
+    | symbTable |
+
+    DisplayTypeMappingTable notNil ifTrue:[ ^ DisplayTypeMappingTable ].
+
+    symbTable := Dictionary new.
+%{
+    __AT_PUT_(symbTable , @symbol(GENERIC),      __MKUINT( RESOURCEDISPLAYTYPE_GENERIC ) );
+    __AT_PUT_(symbTable , @symbol(DOMAIN),       __MKUINT( RESOURCEDISPLAYTYPE_DOMAIN ) );
+    __AT_PUT_(symbTable , @symbol(SERVER),       __MKUINT( RESOURCEDISPLAYTYPE_SERVER ) );
+    __AT_PUT_(symbTable , @symbol(SHARE),        __MKUINT( RESOURCEDISPLAYTYPE_SHARE ) );
+    __AT_PUT_(symbTable , @symbol(FILE),         __MKUINT( RESOURCEDISPLAYTYPE_FILE ) );
+    __AT_PUT_(symbTable , @symbol(GROUP),        __MKUINT( RESOURCEDISPLAYTYPE_GROUP ) );
+    __AT_PUT_(symbTable , @symbol(NETWORK),      __MKUINT( RESOURCEDISPLAYTYPE_NETWORK ) );
+    __AT_PUT_(symbTable , @symbol(ROOT),         __MKUINT( RESOURCEDISPLAYTYPE_ROOT ) );
+    __AT_PUT_(symbTable , @symbol(SHAREADMIN),   __MKUINT( RESOURCEDISPLAYTYPE_SHAREADMIN ) );
+    __AT_PUT_(symbTable , @symbol(DIRECTORY),    __MKUINT( RESOURCEDISPLAYTYPE_DIRECTORY ) );
+    __AT_PUT_(symbTable , @symbol(TREE),         __MKUINT( RESOURCEDISPLAYTYPE_TREE ) );
+    __AT_PUT_(symbTable , @symbol(NDSCONTAINER), __MKUINT( RESOURCEDISPLAYTYPE_NDSCONTAINER ) );
+%}.
+    DisplayTypeMappingTable := Dictionary new.
+
+    symbTable keysAndValuesDo:[:aSYMB :anINT |
+	DisplayTypeMappingTable at: aSYMB put: anINT.
+	DisplayTypeMappingTable at: anINT put: aSYMB. "/ vice versa
+    ].
+    ^ DisplayTypeMappingTable
+!
+
+scopeMappingTable
+    "answer a Dictionary with scopes mapping symbol to integer and vice verca"
+    | symbTable |
+
+    ScopeMappingTable notNil ifTrue:[ ^ ScopeMappingTable].
+
+    symbTable := Dictionary new.
+%{
+    __AT_PUT_(symbTable, @symbol(CONNECTED),  __MKUINT( RESOURCE_CONNECTED ) );
+    __AT_PUT_(symbTable, @symbol(CONTEXT),    __MKUINT( RESOURCE_CONTEXT ) );
+    __AT_PUT_(symbTable, @symbol(GLOBALNET),  __MKUINT( RESOURCE_GLOBALNET ) );
+    __AT_PUT_(symbTable, @symbol(REMEMBERED), __MKUINT( RESOURCE_REMEMBERED ) );
+    __AT_PUT_(symbTable, @symbol(RECENT),     __MKUINT( RESOURCE_RECENT ) );
+%}.
+    ScopeMappingTable := Dictionary new.
+
+    symbTable keysAndValuesDo:[:aSYMB :anINT |
+	ScopeMappingTable at: aSYMB put: anINT.
+	ScopeMappingTable at: anINT put: aSYMB. "/ vice versa
+    ].
+    ^ ScopeMappingTable
+!
+
+typeMappingTable
+    "answer a Dictionary containing types symbols to integer mapping and vice versa"
+    | symbTable |
+
+    TypeMappingTable notNil ifTrue:[ ^ TypeMappingTable].
+
+    symbTable := Dictionary new.
+%{
+    __AT_PUT_(symbTable , @symbol(ANY),      __MKUINT( RESOURCETYPE_ANY ) );
+    __AT_PUT_(symbTable , @symbol(DISK),     __MKUINT( RESOURCETYPE_DISK ) );
+    __AT_PUT_(symbTable , @symbol(PRINT),    __MKUINT( RESOURCETYPE_PRINT ) );
+    __AT_PUT_(symbTable , @symbol(UNKNOWN),  __MKUINT( RESOURCETYPE_UNKNOWN ) );
+    __AT_PUT_(symbTable , @symbol(RESERVED), __MKUINT( RESOURCETYPE_RESERVED ) );
+%}.
+    TypeMappingTable := Dictionary new.
+
+    symbTable keysAndValuesDo:[:aSYMB :anINT |
+	TypeMappingTable at: aSYMB put: anINT.
+	TypeMappingTable at: anINT put: aSYMB. "/ vice versa
+    ].
+    ^ TypeMappingTable
+!
+
+usageMappingTable
+    "answer a Dictionary containing usages symbols to integer mapping and vice versa"
+    | symbTable |
+
+    UsageMappingTable notNil ifTrue:[ ^ UsageMappingTable].
+
+    symbTable := Dictionary new.
+%{
+    __AT_PUT_(symbTable , @symbol(NULL),          __MKUINT( 0 ) );
+    __AT_PUT_(symbTable , @symbol(CONNECTABLE),   __MKUINT( RESOURCEUSAGE_CONNECTABLE ) );
+    __AT_PUT_(symbTable , @symbol(CONTAINER),     __MKUINT( RESOURCEUSAGE_CONTAINER ) );
+    __AT_PUT_(symbTable , @symbol(ATTACHED),      __MKUINT( RESOURCEUSAGE_ATTACHED ) );
+    __AT_PUT_(symbTable , @symbol(ALL),           __MKUINT( RESOURCEUSAGE_ALL ) );
+    __AT_PUT_(symbTable , @symbol(NOLOCALDEVICE), __MKUINT( RESOURCEUSAGE_NOLOCALDEVICE ) );
+    __AT_PUT_(symbTable , @symbol(SIBLING),       __MKUINT( RESOURCEUSAGE_SIBLING ) );
+    __AT_PUT_(symbTable , @symbol(RESERVED),      __MKUINT( RESOURCEUSAGE_RESERVED ) );
+%}.
+    UsageMappingTable := Dictionary new.
+
+    symbTable keysAndValuesDo:[:aSYMB :anINT |
+	UsageMappingTable at: aSYMB put: anINT.
+	UsageMappingTable at: anINT put: aSYMB. "/ vice versa
+    ].
+    ^ UsageMappingTable
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle class methodsFor:'fetch resources'!
+
+fetchResourcesStartingAt: aNetworkResourceOrNil
+    withScope: aScope type: aType usage: aUsage onError: aBlock
+
+    "Fetch all resources from the given network resource or if nil the root system.
+     On success a collection of al network resources is returned.
+     If the open fails, the error block if notNil will be evaluated with the error number
+     and nil is returned.
+
+    self fetchResourcesStartingAt: nil withScope: #GLOBALNET type: #ANY usage: 0
+        onError: [:err| Transcript showCR: err ].
+    "
+    | stream networkResources |
+
+    [
+        stream := self openAt: aNetworkResourceOrNil
+            withScope: aScope type: aType usage: aUsage onError: aBlock.
+
+        stream notNil ifTrue:[
+            |next|
+
+            networkResources := OrderedCollection new.
+
+            [ (next := stream nextOrNil) notNil ] whileTrue:[
+                networkResources add:next.
+            ].
+        ]
+    ] ensure:[
+        stream notNil ifTrue:[ stream close ].
+    ].
+    ^ networkResources.
+!
+
+fetchSystemResourcesWithScope: aScope type: aType usage: aUsage onError: aBlock
+
+    "Fetch all system resources.
+     On success a collection of al network resources is returned.
+     If the open fails, the error block if notNil will be evaluated with the error number
+     and nil is returned.
+
+    self fetchSystemResourcesWithScope: #GLOBALNET type: #ANY usage: 0
+        onError: [:err| Transcript showCR: err ].
+
+    self fetchSystemResourcesWithScope: #REMEMBERED type: #DISK usage: 0
+        onError: [:err| Transcript showCR: err ].
+
+    self fetchSystemResourcesWithScope: #REMEMBERED type: #ANY usage: 0
+        onError: [:err| Transcript showCR: err ].
+    "
+
+    ^ self fetchResourcesStartingAt: nil
+            withScope: aScope type: aType usage: aUsage onError: aBlock
+!
+
+fetchVirtualDrives
+    "answer a collection of virtual drive resources
+
+     self fetchVirtualDrives
+    "
+    ^ self fetchSystemResourcesWithScope: #REMEMBERED type: #DISK usage: 0 onError: nil.
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle class methodsFor:'opening'!
+
+openAt: aResourceOrNil withScope: aScope type: aType usage: aUsage onError: aBlock
+    "Open a handle for network resource enumeratation starting at the given NetworkResource
+     or if nil on the system root. On success the handle will is returned.
+     If the open fails, the error block if notNil will be evaluated with the error number
+     and nil is returned.
+
+    OperatingSystem networkResourceAccessor openOn:nil withScope:#GLOBALNET  type:#ANY  usage:0 onError:nil.
+    OperatingSystem networkResourceAccessor openOn:nil withScope:#REMEMBERED type:#DISK usage:0 onError:nil.
+    "
+    | resourceHandle errorNumber enumScope enumUsage enumType
+      resScope resType resUsage resDisplayType resComment resLocalName resRemoteName resProvider |
+
+    "/ map symbols to integer values.. on error an exception is raised
+    aScope isInteger ifTrue:[ enumScope := aScope ]
+		    ifFalse:[ enumScope := self scopeMappingTable at:aScope ].
+
+    aUsage isInteger ifTrue:[ enumUsage := aUsage ]
+		    ifFalse:[ enumUsage := self usageMappingTable at:aUsage ].
+
+    aType isInteger ifTrue:[ enumType := aType ]
+		   ifFalse:[ enumType := self typeMappingTable at:aType ].
+
+    aResourceOrNil notNil ifTrue:[ | checkAndGetString |
+	resScope := aResourceOrNil scope.
+	resScope isInteger ifFalse:[ resScope := self scopeMappingTable at:resScope ].
+
+	resType := aResourceOrNil type.
+	resType isInteger ifFalse:[ resType := self typeMappingTable at: resType ].
+
+	resUsage := aResourceOrNil usage.
+	resUsage isInteger ifFalse:[ resUsage := self usageMappingTable at: resUsage ].
+
+	resDisplayType := aResourceOrNil displayType.
+	resDisplayType isInteger ifFalse:[ resDisplayType := self displayTypeMappingTable at:resDisplayType ].
+
+	checkAndGetString := [: aString| |string|
+	    aString notNil ifTrue:[
+		self isUsingUnicode
+		    ifTrue: [ string := aString asUnicode16String  ]
+		    ifFalse:[ string := aString asSingleByteString ].
+	    ].
+	    string
+	].
+	resRemoteName  := checkAndGetString value:( aResourceOrNil remoteName ).
+	resLocalName   := checkAndGetString value:( aResourceOrNil localName ).
+	resComment     := checkAndGetString value:( aResourceOrNil comment ).
+	resProvider    := checkAndGetString value:( aResourceOrNil provider ).
+    ].
+    resourceHandle := self new.
+
+%{
+    HANDLE __hEnum;
+    int    __errno;
+    DWORD  __scope = __unsignedLongIntVal( enumScope );
+    DWORD  __usage = __unsignedLongIntVal( enumUsage );
+    DWORD  __type  = __unsignedLongIntVal( enumType );
+
+#ifdef USE_ANSI_NETWORKRESOURCES
+    char           __buffer[ 8192 ];
+    LPNETRESOURCE  __lpnetRes = (LPNETRESOURCE) __buffer;
+    char *         __cp = __buffer + sizeof(NETRESOURCE);
+    char *         __sp;
+#else
+    wchar_t        __buffer[ 8192 ];
+    LPNETRESOURCEW __lpnetRes = (LPNETRESOURCEW) __buffer;
+    wchar_t *      __cp = __buffer + sizeof(NETRESOURCEW);
+    wchar_t *      __sp;
+#endif
+
+    if( resScope == nil ) {
+	__lpnetRes = 0;
+    } else {
+	int __sz;
+
+	ZeroMemory( __buffer, (__cp - __buffer) );
+
+	__lpnetRes->dwScope       = __unsignedLongIntVal( resScope );
+	__lpnetRes->dwType        = __unsignedLongIntVal( resType  );
+	__lpnetRes->dwUsage       = __unsignedLongIntVal( resUsage );
+	__lpnetRes->dwDisplayType = __unsignedLongIntVal( resDisplayType );
+
+	if( resRemoteName != nil ) {
+#ifdef USE_ANSI_NETWORKRESOURCES
+	    __sp = __stringVal(resRemoteName);
+	    __sz = strlen(__sp);
+#else
+	    __sp = __unicode16StringVal(resRemoteName);
+	    __sz = __unicode16StringSize(resRemoteName);
+#endif
+	    for( __lpnetRes->lpRemoteName = __cp; __sz > 0; --__sz ) { * __cp++ = * __sp++; }
+	    *__cp++ = 0;
+	}
+
+	if( resLocalName != nil ) {
+#ifdef USE_ANSI_NETWORKRESOURCES
+	    __sp = __stringVal(resLocalName);
+	    __sz = strlen(__sp);
+#else
+	    __sp = __unicode16StringVal(resLocalName);
+	    __sz = __unicode16StringSize(resLocalName);
+#endif
+	    for( __lpnetRes->lpLocalName = __cp; __sz > 0; --__sz ) { * __cp++ = * __sp++; }
+	    *__cp++ = 0;
+	}
+
+	if( resComment != nil ) {
+#ifdef USE_ANSI_NETWORKRESOURCES
+	    __sp = __stringVal(resComment);
+	    __sz = strlen(__sp);
+#else
+	    __sp = __unicode16StringVal(resComment);
+	    __sz = __unicode16StringSize(resComment);
+#endif
+	    for( __lpnetRes->lpComment = __cp; __sz > 0; --__sz ) { * __cp++ = * __sp++; }
+	    *__cp++ = 0;
+	}
+
+	if( resProvider != nil ) {
+#ifdef USE_ANSI_NETWORKRESOURCES
+	    __sp = __stringVal(resProvider);
+	    __sz = strlen(__sp);
+#else
+	    __sp = __unicode16StringVal(resProvider);
+	    __sz = __unicode16StringSize(resProvider);
+#endif
+	    for( __lpnetRes->lpProvider = __cp; __sz > 0; --__sz ) { * __cp++ = * __sp++; }
+	    *__cp++ = 0;
+	}
+    }
+
+#ifdef DO_WRAP_CALLS
+    do {
+	__threadErrno = 0;
+#ifdef USE_ANSI_NETWORKRESOURCES
+	__errno = STX_API_NOINT_CALL5( "WNetOpenEnum",  WNetOpenEnum,  __scope, __type, __usage, __lpnetRes, & __hEnum );
+#else
+	__errno = STX_API_NOINT_CALL5( "WNetOpenEnumW", WNetOpenEnumW, __scope, __type, __usage, __lpnetRes, & __hEnum );
+#endif
+    } while ((__errno < 0) && (__threadErrno == EINTR));
+#else
+
+#ifdef USE_ANSI_NETWORKRESOURCES
+    __errno = WNetOpenEnum ( __scope, __type, __usage, __lpnetRes, & __hEnum );
+#else
+    __errno = WNetOpenEnumW( __scope, __type, __usage, __lpnetRes, & __hEnum );
+#endif
+
+#endif
+
+    if( __errno == NO_ERROR ) {
+	__externalAddressVal(resourceHandle) = (void *) __hEnum;
+    } else {
+	resourceHandle = nil;
+	errorNumber    = __mkSmallInteger( __errno );
+    }
+
+%}.
+    resourceHandle isNil ifTrue:[
+	aBlock notNil ifTrue:[ aBlock value: errorNumber ].
+	^ nil
+    ].
+    resourceHandle registerForFinalization.
+    ^ resourceHandle
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle class methodsFor:'testing'!
+
+isUsingUnicode
+    "answer true if we are using unicode; has effect to the open and next operation"
+
+%{
+#ifdef USE_ANSI_NETWORKRESOURCES
+    RETURN( false );
+#endif
+%}.
+    ^ true
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle methodsFor:'queries'!
+
+atEnd
+    "answer true if the stream is at the end (no longer valid)"
+    ^ (self address == 0)
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle methodsFor:'reading'!
+
+nextOrNil
+    "answer the next NetworkResource or nil (no more resource available);
+     if no more resource is available the stream is closed"
+
+    | scope type usage displayType comment localName remoteName provider |
+
+    self atEnd ifTrue:[ ^ nil ].
+
+%{
+    HANDLE __hEnum = (HANDLE)(__externalAddressVal(self));
+
+    if ((__hEnum == 0) || (__hEnum == INVALID_HANDLE_VALUE)) {
+	__externalAddressVal(self) = (HANDLE)0;
+    } else {
+	DWORD           __entries = 1;
+	DWORD           __bufSize = 8192;
+	int             __errno;
+
+#ifdef USE_ANSI_NETWORKRESOURCES
+	char            __buffer[ 8192 ];
+	LPNETRESOURCE   __lpNetRes  = (LPNETRESOURCE)  __buffer;
+
+	ZeroMemory( __buffer, sizeof(NETRESOURCE) );
+	__errno = WNetEnumResource ( __hEnum , & __entries , __lpNetRes, & __bufSize );
+#else
+	wchar_t         __buffer[ 8192 ];
+	LPNETRESOURCEW  __lpNetRes  = (LPNETRESOURCEW) __buffer;
+
+	ZeroMemory( __buffer, sizeof(NETRESOURCEW) );
+	__errno = WNetEnumResourceW ( __hEnum , & __entries , __lpNetRes, & __bufSize );
+#endif
+
+	if( (__errno  == NO_ERROR) && (__entries == 1) ) {
+	    scope       = __MKUINT( __lpNetRes->dwScope );
+	    type        = __MKUINT( __lpNetRes->dwType );
+	    usage       = __MKUINT( __lpNetRes->dwUsage );
+	    displayType = __MKUINT( __lpNetRes->dwDisplayType );
+
+#ifdef USE_ANSI_NETWORKRESOURCES
+	    if( __lpNetRes->lpRemoteName != 0 ) { remoteName =  __MKSTRING( __lpNetRes->lpRemoteName ); }
+	    if( __lpNetRes->lpLocalName  != 0 ) { localName  =  __MKSTRING( __lpNetRes->lpLocalName ); }
+	    if( __lpNetRes->lpComment    != 0 ) { comment    =  __MKSTRING( __lpNetRes->lpComment ); }
+	    if( __lpNetRes->lpProvider   != 0 ) { provider   =  __MKSTRING( __lpNetRes->lpProvider ); }
+#else
+	    if( __lpNetRes->lpRemoteName != 0 ) { remoteName =  __MKU16STRING( __lpNetRes->lpRemoteName ); }
+	    if( __lpNetRes->lpLocalName  != 0 ) { localName  =  __MKU16STRING( __lpNetRes->lpLocalName ); }
+	    if( __lpNetRes->lpComment    != 0 ) { comment    =  __MKU16STRING( __lpNetRes->lpComment ); }
+	    if( __lpNetRes->lpProvider   != 0 ) { provider   =  __MKU16STRING( __lpNetRes->lpProvider ); }
+#endif
+	}
+    }
+%}.
+    scope notNil ifTrue:[ |netResource|
+	netResource := NetworkResource new.
+
+	"map integer values to symbol excluding the usage..."
+	netResource scope: (self class scopeMappingTable at:scope ifAbsent:[scope]).
+	netResource type:  (self class typeMappingTable  at:type ifAbsent:[type]).
+	netResource displayType: (self class displayTypeMappingTable at:displayType ifAbsent:[displayType]).
+	netResource usage: usage.
+
+	netResource remoteName: remoteName.
+	netResource localName: localName.
+	netResource comment: comment.
+	netResource provider: provider.
+
+	^ netResource
+    ].
+    self close.
+    ^ nil
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle methodsFor:'release'!
+
+closeHandle
+    "close the handle"
+
+    self address == 0 ifTrue:[ ^ self ].
+%{
+    HANDLE __hEnum = (HANDLE)(__externalAddressVal(self));
+
+    if (__hEnum) {
+	__externalAddressVal(self) = (HANDLE)0;
+	WNetCloseEnum(__hEnum);
+    }
+%}.
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle::NetworkResource methodsFor:'accessing'!
+
+comment
+    "comment supplied by the network provider or nil"
+
+    ^ comment
+!
+
+comment: aStringOrNil
+    "comment supplied by the network provider or nil"
+
+    comment := aStringOrNil.
+!
+
+displayType
+    "The display options for the network object in a network browsing user interface"
+
+    ^ displayType
+!
+
+displayType: theDisplayType
+    "The display options for the network object in a network browsing user interface"
+
+    displayType := theDisplayType.
+!
+
+localName
+    "if the scope member is equal to RESOURCE_CONNECTED or RESOURCE_REMEMBERED,
+     this specifies the name of a local device. This member is NULL if the connection
+     does not use a device."
+
+    ^ localName
+!
+
+localName: aStringOrNil
+    "if the scope member is equal to RESOURCE_CONNECTED or RESOURCE_REMEMBERED,
+     this specifies the name of a local device. This member is NULL if the connection
+     does not use a device."
+
+    localName := aStringOrNil.
+!
+
+provider
+    "the name of the provider that owns the resource or nil"
+
+    ^ provider
+!
+
+provider: aStringOrNil
+    "the name of the provider that owns the resource or nil"
+
+    provider := aStringOrNil.
+!
+
+remoteName
+    "If the resource is a network resource, this specifies the remote network name.
+     If the resource is a current or persistent connection, this specifies the network
+     name associated with the name pointed to by the localName"
+
+    ^ remoteName
+!
+
+remoteName: aStringOrNil
+    "If the resource is a network resource, this specifies the remote network name.
+     If the resource is a current or persistent connection, this specifies the network
+     name associated with the name pointed to by the localName"
+
+    remoteName := aStringOrNil.
+!
+
+scope
+    "The scope of the enumeration
+	RESOURCE_CONNECTED RESOURCE_GLOBALNET RESOURCE_REMEMBERED
+    "
+    ^ scope
+!
+
+scope: theScope
+    "The scope of the enumeration
+	RESOURCE_CONNECTED RESOURCE_GLOBALNET RESOURCE_REMEMBERED
+    "
+    scope := theScope.
+!
+
+type
+    "describes the type of the resource
+	RESOURCETYPE_ANY  RESOURCETYPE_DISK  RESOURCETYPE_PRINT
+    "
+    ^ type
+!
+
+type: theType
+    "describes the type of the resource
+	RESOURCETYPE_ANY  RESOURCETYPE_DISK  RESOURCETYPE_PRINT
+    "
+    type := theType.
+!
+
+usage
+    "a set of bit flags (INTEGER) describing how the resource can be used"
+
+    ^ usage
+!
+
+usage: anInteger
+    "a set of bit flags (INTEGER) describing how the resource can be used"
+
+    usage := anInteger.
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle::NetworkResource methodsFor:'printing'!
+
+printOn: aStream
+    "print self on a stream"
+
+    | paction |
+
+    paction := [: anIdentifier :theValue |
+	anIdentifier printOn: aStream.
+
+	theValue notNil ifTrue:[
+	    theValue isInteger ifTrue:[
+		theValue printOn:aStream base:2 showRadix:true.
+	    ] ifFalse:[
+		theValue isSymbol ifTrue:[
+		    theValue printOn: aStream.
+		] ifFalse:[
+		    aStream nextPut: $". theValue printOn: aStream. aStream nextPut: $"
+		]
+	    ]
+	].
+	aStream cr.
+    ].
+
+    aStream nextPutAll: 'NetworkResource {'; cr.
+
+    paction value: '  Scope:        ' value:scope.
+    paction value: '  Type:         ' value:type.
+    paction value: '  DisplayType:  ' value:displayType.
+    paction value: '  Usage(mask):  ' value:usage.
+
+    aStream cr.
+
+    paction value: '  RemoteName:   ' value:remoteName.
+    paction value: '  LocalName:    ' value:localName.
+    paction value: '  Comment       ' value:comment.
+    paction value: '  Provider      ' value:provider.
+
+    aStream nextPut: $}; cr.
+! !
+
+!Win32OperatingSystem::Win32NetworkResourceHandle::NetworkResource methodsFor:'queries'!
+
+isResourceContainer
+    "answer true if the resource is a resource container"
+
+    | flag |
+
+    usage isInteger ifFalse:[ ^ usage = #CONTAINER ].
+    flag := usage.
+%{
+    DWORD __usage = __unsignedLongIntVal( flag );
+
+    if( __usage & RESOURCEUSAGE_CONTAINER ) {
+	RETURN( true );
+    }
+%}.
+    ^ false
+! !
+
 !Win32OperatingSystem::Win32PrinterHandle methodsFor:'release'!
 
 closeHandle
@@ -16527,11 +17166,11 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.458 2013-04-03 11:46:25 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.459 2013-04-10 08:04:37 ca Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.458 2013-04-03 11:46:25 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.459 2013-04-10 08:04:37 ca Exp $'
 !
 
 version_SVN