[Image] [Image] [Image] [Image] [Image] [Image] [Image] [Return] What Files Are Open? [Return] --------------------------------------------------------------------------- Another useful networking function is the ability to find what files on a given server are open, who opened them, from where and what the ID number is so you can force the connection closed, if the need arises. The function to do this is poorly documented, however, and different between Windows NT and Windows 95. Below is some source code which determines the current platform and calls a file enumeration function appropriate for the found platform. That function, in turn, calls the NetFileEnum() function. Note that structures have been copied from their platform dependent header files to prevent platform dependence and dynamic linking is employed since the function resides in different DLLs, depending on the platform. The server name to examine is obtained from an edit control, ID #101, and any output is displayed in a listbox, ID #100. // === Structures and definitions ============================================= typedef struct file_info_50 { unsigned long fi50_id; unsigned short fi50_permissions; unsigned short fi50_num_locks; char *fi50_pathname; char *fi50_username; char *fi50_sharename; } FILE_INFO_50, * PFILE_INFO_50, * LPFILE_INFO_50; typedef struct _FILE_INFO_3 { DWORD fi3_id; DWORD fi3_permissions; DWORD fi3_num_locks; LPTSTR fi3_pathname; LPTSTR fi3_username; } FILE_INFO_3, *PFILE_INFO_3, *LPFILE_INFO_3; // === Function Called by a Program =========================================== BOOL EnumOpenFiles( HWND hDlg ) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx( &osvi ); // Get the platform version if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) return( EnumOpenFiles95( hDlg ) ); // If Win95, do this else return( EnumOpenFilesNT( hDlg ) ); // If Windows NT, do that return( FALSE ); // Return an error if it's neither } // === Windows 95 File Enumeration Function =================================== BOOL EnumOpenFiles95( HWND hDlg ) { HANDLE hModule; USHORT usRead, usTotal; DWORD dwStatus; char szServer[ 32 ], szStr[ 256 ]; PFILE_INFO_50 pfInfo, opfInfo; DWORD ( CALLBACK *pNetEnumFile )( LPSTR, LPSTR, short, LPVOID, USHORT, USHORT *, USHORT * ); if( ! GetDlgItemText( hDlg, 101, szServer, 32 ) ) return( FALSE ); // Can't continue without a server hModule = LoadLibrary( "SVRAPI.DLL" ); // Load network library if( ! hModule ) return( FALSE ); // The locate the enumeration function address (FARPROC)pNetEnumFile = (FARPROC)GetProcAddress( hModule, "NetFileEnum" ); // Grab some buffer space pfInfo = (PFILE_INFO_50)GlobalAllocPtr( GHND, 4096 ); if( pfInfo ) { opfInfo = pfInfo; // Save original so we can free it later usRead = usTotal = 0; // Now enumerate all open files dwStatus = pNetEnumFile( szServer, NULL, 50, pfInfo, (USHORT)4096, &usRead, &usTotal ); if( ! dwStatus && usRead ) // If it worked and something was read... { while( usRead ) // Loop through each found item { // Send filename to the listbox SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)pfInfo->fi50_pathname ); // Also display the ID, user and sharename wsprintf( szStr, " ID #%d by %s on %s", pfInfo->fi50_id, pfInfo->fi50_username, pfInfo->fi50_sharename ); SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)szStr ); // Send to the listbox and add a blank line SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)" " ); ++pfInfo; --usRead; // Repeat for all found items } } GlobalFreePtr( opfInfo ); // Free the buffer } FreeLibrary( hModule ); // Unload the library and exit return( TRUE ); } // === Windows NT File Enumeration Function =================================== BOOL EnumOpenFilesNT( HWND hDlg ) { HANDLE hModule; DWORD dwStatus, dwRead, dwTotal; char szServer[ 32 ], tszServer[ 256 ]; PFILE_INFO_3 pfi3; DWORD ( CALLBACK *pNetFileEnum )( LPTSTR, LPTSTR, LPTSTR, DWORD, LPBYTE *, DWORD, LPDWORD, LPDWORD, LPDWORD ); if( ! GetDlgItemText( hDlg, 101, szServer, 32 ) ) // No server? No run return( FALSE ); hModule = LoadLibrary( "NETAPI32.DLL" ); if( ! hModule ) // Load the network module or die trying return( FALSE ); // Now get the address of the file enum proc (FARPROC)pNetFileEnum = (FARPROC)GetProcAddress( hModule, "NetFileEnum" ); if( ! pNetFileEnum ) { FreeLibrary( hModule ); // Quit if the proc is not found return( FALSE ); } // Convert char string to unicode string MultiByteToWideChar( CP_ACP, MB_COMPOSITE, szServer, -1, (USHORT *)tszServer, 64 ); // Enum all files open on the specified server dwStatus = pNetFileEnum( tszServer, NULL, NULL, 3, (LPBYTE *)&pfi3, 4096, &dwRead, &dwTotal, NULL ); if( ! dwStatus && dwRead ) // If it worked and something was read... { while( dwRead ) // Display all items found { // Convert unicode filename to char string WideCharToMultiByte( CP_ACP, 0, (USHORT *)pfi3->fi3_pathname, -1, tszServer, 256, NULL, NULL ); // and send to the listbox SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)tszServer ); // Display the file ID and wsprintf( tszServer, " ID #%d by ", pfi3->fi3_id ); // append the name after converting from unicode WideCharToMultiByte( CP_ACP, 0, (USHORT *)pfi3->fi3_username, -1, tszServer + strlen( tszServer ), 256 - strlen( tszServer ), NULL, NULL ); // send to listbox and add a blank line SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)tszServer ); SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)" " ); ++pfi3; --dwRead; // Repeat for each found item } } FreeLibrary( hModule ); // At this point, you might try freeing the memory block returned by // the NetFileEnum() function (you didn't alloc a buffer here, that's // only needed in Win95). I was doing a GlobalFreePtr(), but it would // set off an INT 3 breakpoint, so I removed it for safety return( TRUE ); } // ============================================================================ . .