Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Close shared files programmatically

The company I'm working with has a program written in ye olde vb6, which is updated pretty frequently, and most clients run the executable from a mapped network drive. This actually has surprisingly few issues, the biggest of which is automatic updates. Currently the updater program (written in c++) renames the existing exe, then downloads and places the new version into the old version's place. This generally works fine, but in some environments it simply fails.

The solution is running this command from microsoft:

for /f "skip=4 tokens=1" %a in ('net files') do net files %a /close

This command closes all network files that are shared (well... most) and then the updater can replace the exe.

In C++ I can use the System(""); function to run that command, or I could redirect the output of net files, and iterate through the results looking for the particular file in question and run net file /close command to close them. But it would be much much nicer if there were winapi functions that have similar capabilities for better reliability and future safety.

Is there any way for me to programmatically find all network shared files and close relevant ones?

like image 756
wizebin Avatar asked Sep 10 '15 15:09

wizebin


1 Answers

You can programmatically do what net file /close does. Just include lmshare.h and link to Netapi32.dll. You have two functions to use: NetFileEnum to enumerate all open network files (on a given computer) and NetFileClose to close them.

Quick (it assumes program is running on same server and there are not too many open connections, see last paragraph) and dirty (no error checking) example:

FILE_INFO_2* pFiles = NULL;
DWORD nRead = 0, nTotal = 0;

NetFileEnum(
  NULL, // servername, NULL means localhost
  "c:\\directory\\path", // basepath, directory where VB6 program is
  NULL, // username, searches for all users
  2, // level, we just need resource ID
  (LPBYTE*)&pFiles, // bufptr, need to use a double pointer to get the buffer
  MAX_PREFERRED_LENGTH, // prefmaxlen, collect as much as possible
  &nRead, // entriesread, number of entries stored in pFiles
  &nTotal, // totalentries, ignore this
  NULL //resume_handle, ignore this 
);

for (int i=0; i < nRead; ++i)
    NetFileClose(NULL, pFiles[i].fi2_id);

NetApiBufferFree(pFiles);

Refer to MSDN for details about NetFileEnum and NetFileClose. Note that NetFileEnum may return ERROR_MORE_DATA if more data is available.

like image 197
Adriano Repetti Avatar answered Sep 23 '22 15:09

Adriano Repetti