Once you know how to determine the resources on a network, the next stage is to make a connection. Once a connection is made, the resource can be accessed through the entry in the etwork directory in the Object Store. When making a connection you must specify the resource's UNC (such as "\myservermyresource") and a local name (such as "mylocal"). Once the connection is made, the local name can be used to access resources (such as " etworkmylocalmyfile.txt").
Unlike Windows 98/NT/2000, remembered connections are not reestablished automatically in Windows CE when the device is next powered-on. You can, however, find out about remembered connections by accessing the "HKEY_Local_MachineComm edirconnections" key in the registry (see Chapter 4 for information on accessing the registry).
Listing 3.8 shows how to call WNetAddConnection3 to make a connection by specifying the UNC and local name.
void Listing3_8() { TCHAR szUNCPath[MAX_PATH + 1]; TCHAR szLocalName[MAX_PATH + 1]; NETRESOURCE nr; if(!GetTextResponse(_T("Enter UNC to Connect to:"), szUNCPath, MAX_PATH)) return; if(!GetTextResponse(_T("Enter Local Name:"), szLocalName, MAX_PATH)) return; nr.dwType = RESOURCETYPE_DISK; nr.lpRemoteName = szUNCPath; nr.lpLocalName = szLocalName; // Microsoft Network is only provider nr.lpProvider = NULL; if(WNetAddConnection3(hWnd, &nr, NULL, NULL, CONNECT_UPDATE_PROFILE) != NO_ERROR) cout ≪ _T("Error adding connection: ") ≪ GetLastError() ≪ endl; } |
The WNetAddConnection3 function is passed a NETRESOURCE structure initialized with the type of resource to connect (RESOURCETYPE_DISK), and strings containing the UNC and the local name. The provider name must be set to NULL, since only Microsoft networks are supported. WNetAddConnection3 ignores the other NETRESOURCE members.
In Listing 3.8 the Password and Username parameters in WNetAddConnection3 are passed NULL values, indicating that the default user name and password will be used. The last parameter is passed CONNECT_UPDATE_PROFILE, which causes the registry to be updated to store the UNC and local name for the connection.
Listing 3.9 shows how to disconnect from a network connection. The function prompts the user for the local or UNC name of the connection to be broken, and a call is made to WNetCancelConnection2.
void Listing3_9() { TCHAR szPath[MAX_PATH + 1]; if(!GetTextResponse( _T("Enter UNC or Local Name to disconnect:"), szPath, MAX_PATH)) return; if(WNetCancelConnection2(szPath, CONNECT_UPDATE_PROFILE, TRUE) != ERROR_SUCCESS ) cout ≪ _T("Error disconnecting: ") ≪ GetLastError(); } |
WNetCancelConnection2 | |
---|---|
LPTSTR name | Local name of the resource. |
DWORD flag | CONNECT_UPDATE_PROFILE removes connection information from the registry, otherwise 0. |
BOOL force | TRUE to force disconnection even if resources are in use. |
DWORD Return Value | NO_ERROR on success. |
The WNetConnectionDialog1 function can be used to prompt the user with a dialog for the UNC and local name, and then to make a connection using the supplied information. The dialog displayed by Windows CE is not particularly friendly, since it does not allow browsing. Listing 3.10 shows how the dialog can be displayed and a connection made.
void Listing3_10() { CONNECTDLGSTRUCT cs; DWORD dwResult; NETRESOURCE nr; nr.dwType = RESOURCETYPE_DISK; nr.lpRemoteName = NULL; nr.lpLocalName = NULL; nr.lpProvider = NULL; cs.cbStructure = sizeof(cs); cs.hwndOwner = hWnd; cs.lpConnRes = &nr; cs.dwFlags = 0; dwResult = WNetConnectionDialog1(&cs); if(dwResult == 0xFFFFFFFF) cout ≪ _T("User cancelled") ≪ endl; else if(dwResult != WN_SUCCESS) cout ≪ _T("Error connecting: ") ≪ dwResult ≪ endl; } |
Two structures must be initialized. The NETRESOURCE structure specifies the type of connection to make. The CONNECTDLGSTRUCT structure points to the NETRESOURCE structure, and also specifies the handle of the window that will own the connection dialog.
The WNetDisconnectDialog function displays a list of all connections and allows the user to select one for disconnection. Listing 3.11 shows a call to this function.
void Listing3_11() { DWORD dwResult; dwResult = WNetDisconnectDialog(hWnd, 0); if(dwResult == 0xFFFFFFFF) cout ≪ _T("User cancelled dialog") ≪ endl; else if(dwResult != NO_ERROR) cout ≪ _T("Error disconnecting: ") ≪ GetLastError(); } |
WNetDisconnectDialog | |
---|---|
HWND hwnd | Parent window for disconnect dialog. |
DWORD dwType | Ignored, pass as zero. |
DWORD Return Value | ERROR_SUCCESS indicates success. 0xFFFFFFFF indicates that the user canceled the dialog box. |
The WNetDisconnectDialog1 function gives you more control over the disconnection, such as allowing the disconnection even if resources are being used. This function is passed a DISCDLGSTRUCT structure, and is described in the next section.
Windows CE provides default support for PCL (Printer Control Language) printers. This support includes using printers located on a network. Connections can be made to network printers using the WNetAddConnection3 function. The local name results in an entry being made in the etwork directory in the Object Store. Listing 3.12 shows how to map a printer to a local name.
void Listing3_12() { TCHAR szUNCPath[MAX_PATH + 1], szLocal[MAX_PATH + 1]; NETRESOURCE nr; if(!GetTextResponse( _T("Enter Printer UNC to Connect to:"), szUNCPath, MAX_PATH)) return; if(!GetTextResponse( _T("Enter Local name for printer:"), szLocal, MAX_PATH)) return; nr.dwType = RESOURCETYPE_PRINT; nr.lpRemoteName = szUNCPath; nr.lpLocalName = szLocal; // Microsoft Network is only provider nr.lpProvider = NULL; if(WNetAddConnection3(hWnd, &nr, NULL, NULL, CONNECT_UPDATE_PROFILE) != NO_ERROR) cout ≪ _T("Error adding Printer connection: ") ≪ GetLastError() ≪ endl; } |
Once mapped, the local name can be used to specify a network printer. For example, if the shared printer "\myservermyprinter" is mapped tothe local name "PCLPrint", the printer can be referenced by the name " etworkPCLPrint".
Listing 3.13 shows how to disconnect from a network printer resource using the function WNetDisconnectDialog1.
void Listing3_13() { DWORD dwResult; DISCDLGSTRUCT ds; TCHAR szUNCPath[MAX_PATH + 1]; if(!GetTextResponse( _T("Enter Printer UNC to disconnect from:"), szUNCPath, MAX_PATH)) return; ds.cbStructure = sizeof(ds); ds.hwndOwner = hWnd; ds.lpLocalName = NULL; ds.lpRemoteName = szUNCPath; ds.dwFlags = DISC_NO_FORCE ; dwResult = WNetDisconnectDialog1(&ds); if(dwResult != NO_ERROR) cout ≪ _T("Error disconnecting: ") ≪ GetLastError(); } |
The DISCDLGSTRUCT is initialized to specify the UNC of the printer from which to disconnect. A dialog will only be displayed if an error occurs, and the owner window handle is provided. The connection will not be broken if the printer is currently in use since the DISC_NO_FORCE flag isused.
WNetDisconnectDialog1 | |
---|---|
LPDISCDLGSTRUCT DiscDlgStruc | Long pointer to the DISCDLGSTRUCT data structure, which specifies the behavior for the disconnect attempt. |
DWORD Return Value | ERROR_SUCCESS indicates success. |
You can retrieve the current user's name or the name used to connect to any network resource using the WNetGetUser function as shown in Listing 3.14.
void Listing3_14() { DWORD dwLen = 50; TCHAR szConnection[MAX_PATH + 1]; TCHAR szUser[51]; if(!GetTextResponse(_T("Enter connection to list:"), szConnection, MAX_PATH)) return; if(WNetGetUser(szConnection, szUser, &dwLen) != ERROR_SUCCESS) cout ≪ _T("Error getting user information: ") ≪ GetLastError() ≪ endl; else cout ≪ szConnection ≪ _T("connected as user ") ≪ szUser ≪ endl; } |
WNetGetUser | |
---|---|
LPTSTR localName | Name of the local resource, or NULL for default username |
LPTSTR userName | Buffer to hold the username |
LPDWORD bufferSize | The size of the userName buffer |
DWORD Return Value | Returns ERROR_SUCCESS on success |
If you pass zero or NULL in for the localName parameter, the function returns the name of the current user. If you pass in a device name, the function returns the name used to attach to the device when WNetAddConnection3 was called. The function returns an error code, or you can retrieve the error code with GetLastError.
Listing 3.15 uses FindFirstFile and FindNextFile to iterate through the local connection names in the etwork directory. These entries represent the active connections, and WNetGetConnection is used to determine the UNC to which the local name refers. This code will only show the active connections, since Windows CE will not automatically reestablish the remembered connections. You can write code to list the remembered connections by listing the registry entries under the key "HKEY_Local_MachineComm edirconnections" (see Chapter 4).
void PrintConnectionData(WIN32_FIND_DATA* lpFD) { TCHAR szRemoteName[MAX_PATH + 1]; DWORD dwSize = MAX_PATH; cout ≪ _T("Connection: ") ≪ lpFD->cFileName; if(WNetGetConnection(lpFD->cFileName, szRemoteName, &dwSize) == NO_ERROR) cout ≪ _T(" to ") ≪ szRemoteName ≪ endl; else if(GetLastError() == ERROR_CONNECTION_UNAVAIL) cout ≪ _T(" not currently connected."); else cout ≪ _T(" Error calling WNetGetConnection ") ≪ GetLastError() ≪ endl; } void Listing3_15() { HANDLE hFindFile; WIN32_FIND_DATA fdData; // get first file hFindFile = FindFirstFile( _T("\network\*.*"), &fdData); if(hFindFile != INVALID_HANDLE_VALUE) { PrintConnectionData(&fdData); while(FindNextFile(hFindFile, &fdData)) { PrintFindData(&fdData); } FindClose(hFindFile); } else if(GetLastError() == ERROR_NO_MORE_FILES) cout ≪ _T("No shares"); else cout ≪ _T("Call to FindFirstFile failed: ") ≪ GetLastError(); } |
The function WNetGetConnection is passed the local file name (in lpFD->cFilename), and returns the UNC name in a character buffer.
tConnection | |
---|---|
LPCTSTR LocalName | Long pointer to a null-terminated string that specifies the local name of the network resource. Set up this resource with the WNetAddConnection3 function. |
LPTSTR RemoteName | Long pointer to a buffer that receives the UNC. |
LPDWORD Length | Long pointer to a variable that specifies the size, in characters, of the buffer pointed to by the lpRemoteName parameter. If the function fails because the buffer is not big enough, this parameter returns the required buffer size. |
DWORD Return Value | ERROR_SUCCESS on success. |
3.23.101.60