2

I am seeking to add functionality within a windows dll to detect the name of a calling Python script.

I am calling the dll via Python using ctypes as described in the answers to How can I call a DLL from a scripting language?

Within the dll I'm able to successfully determine the calling process using WINAPI GetModuleFileName() http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx. However, since this is a Python script it's being run via the Python executable thus the returned module file name is "C:/Python33/Python.exe". I'm needing the name of the actual script file doing the call. Is this possible?

A bit of background on why: this dll is used for authentication. It's generating a hash using a shared secret key for the script to use to authenticate an HTTP request. It's embedded in the dll so that people using the script won't see the key. We want to make sure the python file calling the script is signed so not just anyone can use this dll to generate a signature, so getting the filepath of the calling script is the first step.

Community
  • 1
  • 1
Serdmanczyk
  • 1,133
  • 7
  • 13

1 Answers1

3

Generically, without using the Python C-API, you can get the process command line and parse it into an argv array using Win32 GetCommandLine and CommandLineToArgvW. Then check if argv[1] is a .py file.

Python demo, using ctypes:

import ctypes
from ctypes import wintypes

GetCommandLine = ctypes.windll.kernel32.GetCommandLineW
GetCommandLine.restype = wintypes.LPWSTR
GetCommandLine.argtypes = []

CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
CommandLineToArgvW.restype = ctypes.POINTER(wintypes.LPWSTR)
CommandLineToArgvW.argtypes = [
    wintypes.LPCWSTR,  # lpCmdLine,
    ctypes.POINTER(ctypes.c_int),  # pNumArgs
]

if __name__ == '__main__':
    cmdline = GetCommandLine()
    argc = ctypes.c_int()
    argv = CommandLineToArgvW(cmdline, ctypes.byref(argc))
    argc = argc.value
    argv = argv[:argc]
    print(argv)
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
  • Ah, of course. I'm looking to do the checking not in the Python script, but within the dll being called by the Python script but your answer provides enough info. By using GetCommandLine() within the dll I'll be able to discern the filename of the script to check if it's signed, thanks! – Serdmanczyk May 21 '13 at 17:12