[python-win32] Calling random Windows function?

Aahz aahz at pythoncraft.com
Sat Oct 24 01:04:23 CEST 2009


On Fri, Oct 23, 2009, Tim Golden wrote:
> Aahz wrote:
>> 
>> Wow!  Thanks!  Now that I know more what to look for, I did some
>> searching and found this post that had no response:
>>
>> http://mail.python.org/pipermail/python-win32/2009-June/009268.html
>>
>> Assuming that I only care about monitoring open files within a single
>> tree, should I be concerned that your code might not return all open
>> files?
>
> Obviously, the answer would depend on the parameters of what you're
> trying to do and how much margin of error you have. One definite
> gotcha I wasn't totally able to work around -- although the code in
> can_access is trying -- is the issue that attempting to query for
> a pipe handle can hang the thread altogether. I believe that the
> poster in the thread you refer to above didn't have any such problem
> (we had a private correspondence which led up to that post).

Perhaps it would be better to think more strategically.  I don't actually
care about the list of open files.  What I care about is a list of files
that I want to process and checking whether any of them are open.  What
would be the canonical way of doing that on Windows?  It doesn't matter
whether it is in batch or file-by-file.

> If you believe that your C++ code is definitely working and you're
> free to post it up, I for one am happy to help you translate it.
> Maybe that's an option...

Hah.  We have no reason to believe that the code is working (other than
the fact that it appears to work), but I'm attaching it in case you find
it useful.  If you want the whole project, I can get that, too.

> PS Welcome to the world of Python on Windows!

Thanks!
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"In the end, outside of spy agencies, people are far too trusting and
willing to help."  --Ira Winkler
-------------- next part --------------
// Open_File_find.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Open_File_find.h"
//#include <Winternl.h>
#include <Psapi.h>
#include <Tlhelp32.h>
#include "Utils.h"
#include <shlwapi.h>
#include <fstream>

#include <iostream>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define VISTA_FILETYPE  25
#define XP_FILETYPE 28

#define BUFSIZE 33000

PNtQuerySystemInformation NtQuerySystemInformation;

struct PROCESS_INFO_t
{
    CString csProcess;
    DWORD dwImageListIndex;
};

CMap<int,int,PROCESS_INFO_t,PROCESS_INFO_t&> m_stProcessInfo;
CString gFolderName;



void EnumerateOpenedFiles( HANDLE hDriver )
{
	int nFileType = VISTA_FILETYPE;
	OSVERSIONINFO info = { 0 }; 
	info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&info); 
	if( info.dwMajorVersion == 5 )
	{
		nFileType = XP_FILETYPE;
	}
	CString csPath = gFolderName;    
    csPath.MakeLower();
	CString csShortName;

    int lengthStr = GetShortPathName( csPath, csShortName.GetBuffer( MAX_PATH), MAX_PATH );
	if (lengthStr == 0) OutputDebugString(L"GetShortPathName() call failed!");
    csShortName.ReleaseBuffer();
    csShortName.MakeLower();

    bool bShortPath = false;
    if(  csShortName != csPath && FALSE == csShortName.IsEmpty())
    {
        bShortPath = true;
    }

	// Get the list of all handles in the system
    PSYSTEM_HANDLE_INFORMATION pSysHandleInformation = new SYSTEM_HANDLE_INFORMATION;
    DWORD size = sizeof(SYSTEM_HANDLE_INFORMATION);
    DWORD needed = 0;
    NTSTATUS status = NtQuerySystemInformation( SystemHandleInformation, pSysHandleInformation, size, &needed );
    if( !NT_SUCCESS(status))
    {
        if( 0 == needed )
        {
            return;// some other error
        }
        // The previously supplied buffer wasn't enough.
        delete pSysHandleInformation;
        size = needed + 1024;
        pSysHandleInformation = (PSYSTEM_HANDLE_INFORMATION)new BYTE[size];
        status = NtQuerySystemInformation( SystemHandleInformation, pSysHandleInformation, size, &needed );
        if( !NT_SUCCESS(status))
        {
            // some other error so quit.
			delete pSysHandleInformation;
			return;
        }
    }
    //int nCount = m_list.GetItemCount() - 1;
	//fstream fout;
	// fout.open ("log.txt", fstream::in | fstream::out |fstream::trunc);

	// Walk through the handle list
    for ( DWORD i = 0; i < pSysHandleInformation->dwCount; i++ )
	{
        SYSTEM_HANDLE& sh = pSysHandleInformation->Handles[i];
        if( sh.bObjectType != nFileType )// Under windows XP file handle is of type 28
        {
            continue;
        }
        HANDLE_INFO stHandle = {0};
		ADDRESS_INFO stAddress;
		stAddress.pAddress = sh.pAddress;
		DWORD dwReturn = 0;
		BOOL bSuccess = DeviceIoControl( hDriver, IOCTL_LISTDRV_BUFFERED_IO, &stAddress, sizeof(ADDRESS_INFO), 
										 &stHandle, sizeof(HANDLE_INFO), &dwReturn, NULL );
		
		
		//File.Write(_T("\n"),sizeof("\n"));
		//_tprintf(_T("%s\n"),stHandle.tcFileName);
		//CString temp;
		//temp=(LPCTSTR)stHandle.tcFileName;
        //fout<<(LPCTSTR)stHandle.tcFileName<<"\n";
		

        if( bSuccess && stHandle.tcFileName[0] != 0 && 
            stHandle.uType != FILE_DEVICE_SOUND && 
            stHandle.uType != FILE_DEVICE_NAMED_PIPE )
        {
            CString csFileName;
            
            if( stHandle.uType != FILE_DEVICE_NETWORK_FILE_SYSTEM  )
            {
                // Get the drive name from the dos device name
                if( !GetDrive( (LPCTSTR)stHandle.tcDeviceName, csFileName, true ))
			    {
				    OutputDebugString( L"GetDrive failed" );
			    }
				//_tprintf(_T("stHandle.tcFilename=%s \n "),stHandle.tcFileName);
                csFileName += (LPCTSTR)stHandle.tcFileName;

				//TESTING..
				//CString strUNC = _T("\\"+"\\"+"?"+"\\");
				//CString strUNC = _T("\\"+"\\"+"?"+"\\");
				CString strUNC = _T("\\\\?\\");
				if(csPath.Find(_T("\\\\?\\")) != -1) //the search string found!
				{
					csFileName = strUNC + csFileName;
				}
            }
            else
            {
                csFileName = _T("\\");
                csFileName += (LPCTSTR)stHandle.tcFileName;
            }
			
            //_tprintf(_T("csFilename=%s \n "),csFileName);
            csFileName.MakeLower();
			// Check whether the file belongs to the specified folder
            if( -1 == csFileName.Find( csPath ))
            {
				if( bShortPath )
				{
					// Some times the file name may be in short path form.
					if( -1 == csFileName.Find( csShortName ))
					{
						OutputDebugString( L"" );
						continue;
					}
				}
				else
				{
					continue;
				}
			}
			//_tprintf(_T("Filename1=%s \n "),csFileName);
            PROCESS_INFO_t stInfo;			
            stInfo.dwImageListIndex = 0;
			if( sh.dwProcessId == 4 )// check whether the process is system
			{			
				stInfo.csProcess = "System";
                
			}
			else
			{
                
                if( !m_stProcessInfo.Lookup( sh.dwProcessId, stInfo ))
                {
                    CString csProcessName = _T("<Un known>");
				    // Get the process file name
				    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, TRUE, sh.dwProcessId );
				    if( hProcess != 0 )
				    {                        
					    LPTSTR lpPath = csProcessName.GetBuffer( MAX_PATH);
					    BOOL b = GetProcessImageFileName( hProcess, lpPath, MAX_PATH );
					    if( b )                    
					    {
						    PathStripPath( lpPath );
						    csProcessName.ReleaseBuffer();
					    }                
					    else
					    {
						    csProcessName.ReleaseBuffer();
					    }                
					    CloseHandle( hProcess );
				    }
                    stInfo.csProcess = csProcessName;
                    stInfo.dwImageListIndex = -1;
                }

                
                
			}

			TCHAR  buffer[BUFSIZE]=TEXT("");
			TCHAR** lppPart={NULL};
			DWORD  retval=0;
			//retval = GetFullPathName(csFileName,
			//							BUFSIZE,
			//							buffer,
			//							NULL);
			retval = GetLongPathName(csFileName,
									  buffer,
									  BUFSIZE);

			if (retval == 0) 
			{
				// Handle an error condition.
				_tprintf (_T("GetLongPathName for %s failed (System Error: %d)\n"), csFileName, GetLastError());
//##			return;
			}
			/*else 
			{
				_tprintf(_T("The full path name is:  %s\n"), buffer);
				if (lppPart != NULL && *lppPart != 0)
				{
					_tprintf(_T("The final component in the path name is:  %s\n"), *lppPart);
				}
			}*/


			_tprintf(_T("%s\t"),stInfo.csProcess);
			_tprintf(_T("%s\n\n"),buffer);
			

			// Insert Process name, PID and file name
           /* m_list.InsertItem( ++nCount, stInfo.csProcess, stInfo.dwImageListIndex );                    
            CString csPid;
            csPid.Format( _T("%d ( 0x%x )"), sh.dwProcessId , sh.dwProcessId );			
            m_list.SetItemText( nCount, 1, csPid );
            m_list.SetItemText( nCount, 2, csFileName );
            m_list.SetItemData( nCount, sh.wValue );*/
        }
        
    }
    delete pSysHandleInformation;

}

// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		nRetCode = 1;
	}
	else
	{
///////////////////////////////////////////////////////////////////////////////	
		gFolderName = argv[1];
		int nFileType = XP_FILETYPE;
		
		EnableTokenPrivilege( SE_DEBUG_NAME );
		HANDLE hDriver = ExtractAndInstallDrv();
		if( hDriver )
        {
			HMODULE hModule = LoadLibrary( _T("ntdll.dll"));
			if( !hModule )
			{
				OutputDebugString( L"Loading ntdll failed\n" );
				return 0;
			}
			NtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress( hModule, "NtQuerySystemInformation" );
			if( 0 == NtQuerySystemInformation )
			{
				OutputDebugString( L"Getting proc of NtQuerySystemInformation failed" );
			}

			// Now walk all handles
            EnumerateOpenedFiles( hDriver );
			
			// Time to wind up
			FreeLibrary( hModule );
            StopAndUninstallDrv( hDriver );
        }
		else
		{
			_tprintf(_T("Fatal Error: Driver Handle couldn't be obtained.\nExiting..\n"));
		}


/////////////////////////////////////////////////////////////////////////////////
		// TODO: code your application's behavior here.
	}
	
	/*if(!CreateDirectory(_T("\\\\?\\D:\\Divya1\\Egnyte\\The Microsoft Windows operating system supports thousands of devices. TEST More than 30,000 drivers have been released, and more are introduced daily. Some of these drivers are based on models that were designed more than 10 years ago\\The Microsoft Windows operating system supports thousands of devices. More than 30,000 drivers have been released, and more are introduced daily. Some of these drivers are based on models that were designed more than 10 years ago"),NULL))//\\"), NULL) )\\The Microsoft Windows operating system supports thousands of devices. More than 30,000 drivers have been released, and more are introduced daily. Some of these drivers are based on models that were designed more than 10 years ago
	{
		_tprintf(_T("Directory couldn not be created!\n"));
	}*/

	/*
	HANDLE hFile = CreateFile(_T("\\\\?\\D:\\Divya1\\Egnyte\\The Microsoft Windows operating system supports thousands of devices. TEST More than 30,000 drivers have been released, and more are introduced daily. Some of these drivers are based on models that were designed more than 10 years ago\\The Microsoft Windows operating system supports thousands of devices. More than 30,000 drivers have been released, and more are introduced daily. Some of these drivers are based on models that were designed more than 10 years ago\\Test.doc"),                // name of the write
                       GENERIC_WRITE,          // open for writing
                       0,                      // do not share
                       NULL,                   // default security
                       CREATE_ALWAYS,          // overwrite existing
                       FILE_ATTRIBUTE_NORMAL,  // normal file
                       NULL);                  // no attr. template
	*/
	
	return nRetCode;
}


More information about the python-win32 mailing list