Solved

LPCTSTR in C#

Posted on 2004-04-09
8
4,349 Views
Last Modified: 2012-05-04
Hello.

        I am making an application where I am including two projects in one. First is a managed C++ dll creator and the second is a c# test application using the above as a reference.
        The problem is that I am using a function which has arguments as LPCTSTR in managed c++ but when I try to pass arguments to this function from c# (which I pass as string) I get an error : cannot convert from 'string' to 'sbyte*'.
               
In Managed C++
      DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);
In c#
       filterDriver.LoadDriver("driver.sys","\\c:\windows\\system32", null, true);

Kindly help.
Thanks.
0
Comment
Question by:amidya
8 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 125 total points
ID: 10789684
LPCTSTR is unmanaged pointer. To convert managed string to unmanaged pointer you need to use Marshal.StringToHGlobalAnsi or Marshal.StringToHGlobalUni Methods:

String s1 = "driver.sys";
String s2 = "\\c:\windows\\system32";

IntPtr p1 = Marshal.StringToHGlobalAnsi(s1);
IntPtr p2 = Marshal.StringToHGlobalAnsi(s2);

filterDriver.LoadDriverp1,p2, IntPtr.Zero, true);

Marshal.FreeCoTaskMem(p1);
Marshal.FreeCoTaskMem(p2);

Replace StringToHGlobalAnsi to StringToHGlobalUni if C++ application is UNICODE.
By the way, if you want to use LoadDriver function from C#, make it's interface pure managed: (String, String, String, int)



0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 10793322
Are you programming unmanaged C#? You can avoid unmanaged C# and use attributes (MarshalAs) to define how managed types are marshalled.
0
 

Expert Comment

by:Ownasaurus
ID: 10794546
Also, do u mean "\\c:\\windows\\system32" instead of "\\c:\windows\\system32"?
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:amidya
ID: 10795790
This is with reference to the answer posted by Mr. Alex.

Sir, I am getting an error msg:

cannot convert from 'System.IntPtr' to 'sbyte*'

Please clarify.

Thanks.
0
 

Author Comment

by:amidya
ID: 10795816
THE FOLLOWING IS MY C++ .DLL PROJECT BEING USED BY A C# APPLICATION

namespace mydriver
{
      public __gc class TDriver
      {
            private:
                  HANDLE driverHandle;      //driver handle
                  LPTSTR driverName;            //driver name
                  LPTSTR driverPath;            //driver disk path
                  LPTSTR driverDosName;      //driver's dos name, to link with it
                  bool initialized;      //variables to store the status of this class
                  bool started;
                  bool loaded;
                  bool removable;
                  //get a handle to the driver
                  DWORD OpenDevice(void);      
            
            public:
                  TDriver();
                  ~TDriver();
                  //functions to initialized the driver variables
                  DWORD InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName);
                  DWORD InitDriver(LPCTSTR path);

                  //functions to load and unload drivers. If start = TRUE, the driver will be started.
                  DWORD LoadDriver(bool start);
                  //DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);
                  DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);

                  DWORD LoadDriver(LPCTSTR path, bool start);

                  //if forceClearData == TRUE, will remove variables although we cant remove driver "service"
                  DWORD UnloadDriver(bool forceClearData);
      
                  //functions to start and stop, driver "service"
                  DWORD StartDriver();
                  DWORD StopDriver();

                  bool IsStarted();
                  bool IsLoaded();
                  bool IsInitialized();
                  void SetRemovable(bool value);

                  //funtions to make IO operation with driver
                  DWORD WriteIo(DWORD code, PVOID buffer, DWORD count);
                  DWORD ReadIo(DWORD code, PVOID buffer, DWORD count);
                  DWORD RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount);

                  //function to get driver handle
                  HANDLE GetDriverHandle(void);
      
      };

      TDriver::TDriver()            //constructor
      {
            //Constructor. Initialize variables.
            driverHandle = NULL;
            removable = true;
            driverName = NULL;
            driverPath = NULL;
            driverDosName = NULL;
            initialized = false;
            loaded = false;
            started = false;
      }
                  
      TDriver::~TDriver()            //destructor
      {
            if(driverHandle != NULL)
            {
                  CloseHandle(driverHandle);
                  driverHandle = NULL;
            }
          UnloadDriver(false);
      }

      //if true, the driver havent been removed at finish
      void TDriver::SetRemovable(bool value)
      {
            removable = value;
      }

      //funtion to return class status
      bool TDriver::IsInitialized()
      {
            return initialized;
      }

      //is driver loaded?
      bool TDriver::IsLoaded(void)
      {
            return loaded;
      }

      //is driver started?
      bool TDriver::IsStarted(void)
      {
            return started;
      }

//Init the driver class variables
DWORD TDriver::InitDriver(LPCTSTR path)
{
      //if already initialized, first unload
      if(initialized)
      {
            if(UnloadDriver(false) != DRV_SUCCESS)
                  return DRV_ERROR_ALREADY_INITIALIZED;
      }

      //if yes, i analized the path to extract driver name
      driverPath = (LPTSTR)malloc(strlen(path) + 1);

      if(driverPath == NULL)
            return DRV_ERROR_MEMORY;

      strcpy(driverPath, path);


      //first i search the last backslash
      LPTSTR sPos1 = strrchr(driverPath, (int)'\\');

      //if NULL, the string havent any backslash
      if (sPos1 == NULL)
            sPos1 = driverPath;


      //now, i search .sys
      LPTSTR sPos2 = strrchr(sPos1, (int)'.');

      if (sPos2 == NULL || sPos1 > sPos2)
      {
            free(driverPath);
            driverPath = NULL;

            return DRV_ERROR_INVALID_PATH_OR_FILE;
      }
      
      //extract the driver name
      driverName = (LPTSTR) malloc (sPos2 - sPos1);
      
      if(driverName == NULL)
      {
            free(driverPath);
            driverPath = NULL;

            return DRV_ERROR_MEMORY;
      }

      memcpy(driverName, sPos1 + 1, sPos2 - sPos1 - 1);
      
      driverName[sPos2 - sPos1 - 1] = 0;

      //driverDosName = \\.\driverName
      driverDosName = (LPTSTR) malloc (strlen(driverName) + 5);

      if(driverDosName == NULL)
      {
            free(driverPath);
            driverPath = NULL;

            free(driverName);
            driverName = NULL;

            return DRV_ERROR_MEMORY;
      }

      sprintf(driverDosName, "\\\\.\\%s", driverName);

            
      initialized = true;
      return DRV_SUCCESS;
}


//Init the driver class variables
DWORD TDriver::InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName)
{      
      //if already initialized, first unload
      if(initialized)
      {
            if(UnloadDriver(false) != DRV_SUCCESS)
                  return DRV_ERROR_ALREADY_INITIALIZED;
      }

      LPTSTR dirBuffer;

      //if the user introduced path, first i will ckeck it
      if (path != NULL)
      {
            //if yes, copy in auxiliar buffer and continue
            DWORD len = (DWORD)(strlen(name) + strlen(path) + 1);
            dirBuffer = (LPTSTR) malloc (len);

            if(dirBuffer == NULL)
                  return DRV_ERROR_MEMORY;

            strcpy(dirBuffer, path);

      }

      else
      {
            //if the user dont introduced path, i search in curren directory
            LPTSTR pathBuffer;
        DWORD len = GetCurrentDirectory(0, NULL);
     
            pathBuffer = (LPTSTR) malloc (len);

            if(pathBuffer == NULL)
                  return DRV_ERROR_MEMORY;

                   
        if (GetCurrentDirectory(len, pathBuffer) != 0)
            {
                  len = (DWORD)(strlen(pathBuffer) + strlen(name) + 6);
                  dirBuffer = (LPTSTR) malloc (len);

                  if(dirBuffer == NULL)
                  {
                        free(pathBuffer);

                        return DRV_ERROR_MEMORY;
                  }

                  //complete de total path, currentdirectory\driverName.sys
                  sprintf(dirBuffer, "%s\\%s.sys", pathBuffer, name);

                  //exists this file?
                  if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
                  {
                        free(pathBuffer);
                        free(dirBuffer);

                        //if no, i search in \system32\drivers\
                        LPCTSTR sysDriver = "\\system32\\Drivers\\";
                        LPTSTR sysPath;
                   
                        //i have to get the windows directory
                        DWORD len = GetWindowsDirectory(NULL, 0);
                       sysPath = (LPTSTR) malloc (len + strlen(sysDriver));

                        if(sysPath == NULL)
                              return DRV_ERROR_MEMORY;

                        if (GetWindowsDirectory(sysPath, len) == 0)
                        {
                              free(sysPath);
                              
                              return DRV_ERROR_UNKNOWN;
                        }
      
                        //complete the path and check it
                        strcat(sysPath, sysDriver);
                        len = (DWORD)(strlen(sysPath) + strlen(name) + 5);

                        dirBuffer = (LPTSTR) malloc (len);

                        if(dirBuffer == NULL)
                              return DRV_ERROR_MEMORY;

                        sprintf(dirBuffer, "%s%s.sys", sysPath, name);

                        free(sysPath);

                        //if the file neither exist, i dont know where is it -> i dont initialize
                        if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
                        {
                              free(dirBuffer);

                              return DRV_ERROR_INVALID_PATH_OR_FILE;
                        }
                  }
        }

            else
            {
                  free(pathBuffer);

                  return DRV_ERROR_UNKNOWN;
            }
      }
      
      //Write driver's variables with obtained data
      driverPath = dirBuffer;

      driverName = (LPTSTR)malloc(strlen(name) + 1);

      if(driverName == NULL)
      {
            free(driverPath);
            driverPath = NULL;
            
            return DRV_ERROR_MEMORY;
      }

      strcpy(driverName, name);
      
      LPCTSTR auxBuffer;
      if(dosName != NULL)
        auxBuffer = dosName;
      
      else
            auxBuffer = name;

      //dosName=\\.\driverName
      if(auxBuffer[0] != '\\' && auxBuffer[1] != '\\')
      {
            driverDosName = (LPTSTR) malloc (strlen(auxBuffer) + 5);

            if(driverDosName == NULL)
            {
                  free(driverPath);
                  driverPath = NULL;

                  free(driverName);
                  driverName = NULL;

                  return DRV_ERROR_MEMORY;
            }

            sprintf(driverDosName, "\\\\.\\%s", auxBuffer);
      }

      else
      {
            driverDosName = (LPTSTR) malloc (strlen(auxBuffer));

            if(driverDosName == NULL)
            {
                  free(driverPath);
                  driverPath = NULL;

                  free(driverName);
                  driverName = NULL;

                  return DRV_ERROR_MEMORY;
            }

            strcpy(driverDosName, auxBuffer);
      }

      //set the state to initialized
      initialized = true;

      return DRV_SUCCESS;
}


//Function to Load the driver.
DWORD TDriver::LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start)
{
      //first initialized it
      DWORD retCode = InitDriver(name, path, dosName);

      //then load
      if(retCode == DRV_SUCCESS)
            retCode = LoadDriver(start);

      return retCode;
}

//Function to load the driver
DWORD TDriver::LoadDriver(LPCTSTR path, bool start)
{
      //first initialized it
      DWORD retCode = InitDriver(path);

      //then load
      if(retCode == DRV_SUCCESS)
            retCode = LoadDriver(start);

      return retCode;
}


//Function to Load the driver
DWORD TDriver::LoadDriver(bool start)
{
      //if the driver is already started, i havent to do nothing
      if(loaded)
            return DRV_SUCCESS;

      if(initialized==false)
            return DRV_ERROR_NO_INITIALIZED;

      //Open Service manager to create the new "service"
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode = DRV_SUCCESS;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

   

    //Create the driver "service"
    SC_HANDLE  SCService = CreateService(SCManager,                    // SCManager database
                                                           driverName,            // nombre del servicio
                                                           driverName,            // nombre a mostrar
                                                             SERVICE_ALL_ACCESS,    // acceso total
                                                             SERVICE_KERNEL_DRIVER, // driver del kernel
                                                             SERVICE_DEMAND_START,  // comienzo bajo demanda
                                                             SERVICE_ERROR_NORMAL,  // control de errores normal
                                                             driverPath,                // path del driver
                                                             NULL,                  // no pertenece a un grupo
                                                             NULL,                  // sin tag
                                                             NULL,                  // sin dependencias
                                                             NULL,                  // cuenta local del sistema
                                                             NULL                   // sin password
                                                             );
   
      //if i cant create, first i check if the driver already was loaded.
      if (SCService == NULL)
      {
            SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
            
            if (SCService == NULL)
                  retCode = DRV_ERROR_SERVICE;
      }

    CloseServiceHandle(SCService);
      SCService=NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //if all ok, update the state and start if necessary
      if(retCode == DRV_SUCCESS)
      {
            loaded = true;

            if(start)
                  retCode = StartDriver();
      }

      return retCode;
}


//Function to Unload a driver
DWORD TDriver::UnloadDriver(bool forceClearData)
{
      DWORD retCode = DRV_SUCCESS;

      //if the driver is started, first i will stop it
      if (started)
      {
            if ((retCode = StopDriver()) == DRV_SUCCESS)
            {
                  //i only remove it, if it is mark to be removable
                  if(removable)
                  {
                        //open service and delete it
                        SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
                        
                        if (SCManager == NULL)
                              return DRV_ERROR_SCM;

                        SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
                        
                        if (SCService != NULL)
                        {
                              if(!DeleteService(SCService))
                                    retCode = DRV_ERROR_REMOVING;
                              else
                                    retCode = DRV_SUCCESS;
                        }

                        else
                              retCode = DRV_ERROR_SERVICE;

                        CloseServiceHandle(SCService);
                        SCService = NULL;

                        CloseServiceHandle(SCManager);
                        SCManager = NULL;

                        //if all ok, update the state
                        if(retCode == DRV_SUCCESS)
                              loaded = false;
                  }
            }
      }

      //if the driver is initialized...
      if(initialized)
      {
            //if there was some problem but i mark foreceClear, i will remove the data
            if(retCode != DRV_SUCCESS && forceClearData == false)
                  return retCode;
            
            //update the state
            initialized = false;
                        
            //free memory
            if(driverPath != NULL)
            {
                  free(driverPath);
                  driverPath = NULL;
            }


            if(driverDosName != NULL)
            {
                  free(driverDosName);
                  driverDosName = NULL;
            }

            if(driverName != NULL)
            {
                  free(driverName);
                  driverName = NULL;
            }

      }

      return retCode;
}

//Function to start the driver "service"
DWORD TDriver::StartDriver(void)
{
      //if already started, all ok
      if(started)
            return DRV_SUCCESS;

      //open the service manager and the service and change driver state
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

    SC_HANDLE SCService = OpenService(SCManager,
                                          driverName,
                                              SERVICE_ALL_ACCESS);
   
      if (SCService == NULL)
        return DRV_ERROR_SERVICE;

   
    if (!StartService( SCService, 0, NULL))
      {
            //if the driver was started before i try to do it,
            //i will not remove, because it was created by other application
        if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
            {
                  removable = false;

                  retCode = DRV_SUCCESS;
            }

            else
                  retCode = DRV_ERROR_STARTING;
    }

      else
            retCode = DRV_SUCCESS;

 
    CloseServiceHandle(SCService);
      SCService = NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //update the state and open device
      if(retCode == DRV_SUCCESS)
      {
            started = true;

            retCode = OpenDevice();
      }

    return retCode;
}



//Function to stop driver "service"
DWORD TDriver::StopDriver(void)
{
      //if already stopped, all ok
      if(started==false)
            return DRV_SUCCESS;

      //open the service manager and the service and change driver state
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

   
    SERVICE_STATUS  status;

    SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
   
      if (SCService != NULL)
      {
            //close the driver handle too
            CloseHandle(driverHandle);
            driverHandle = NULL;

            if(!ControlService(SCService, SERVICE_CONTROL_STOP, &status))
                  retCode = DRV_ERROR_STOPPING;

            else
                  retCode = DRV_SUCCESS;
      }

      else
            retCode = DRV_ERROR_SERVICE;


    CloseServiceHandle(SCService);
      SCService = NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //update the state
      if(retCode == DRV_SUCCESS)
            started = false;

    return retCode;
}


//Funtion to open a driver handle
DWORD TDriver::OpenDevice(void)
{
      //if i already have a handle, first close it
      if (driverHandle != NULL)
            CloseHandle(driverHandle);

    driverHandle = CreateFile(driverDosName,
                                            GENERIC_READ | GENERIC_WRITE,
                                            0,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);


    if(driverHandle == INVALID_HANDLE_VALUE)
            return DRV_ERROR_INVALID_HANDLE;
      
      return DRV_SUCCESS;
}


//Return the driverHandle obtained
HANDLE TDriver::GetDriverHandle(void)
{
      return driverHandle;
}


//Funtion to send data to the driver
DWORD TDriver::WriteIo(DWORD code, PVOID buffer, DWORD count)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;

      bool returnCode = DeviceIoControl(driverHandle,
                                                      code,
                                                      buffer,
                                                      count,
                                                      NULL,
                                                      0,
                                                      &bytesReturned,
                                                      NULL);

      if(!returnCode)
            return DRV_ERROR_IO;

      return DRV_SUCCESS;
}


//Functions to read data from the driver
DWORD TDriver::ReadIo(DWORD code, PVOID buffer, DWORD count)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;
      bool retCode = DeviceIoControl(driverHandle,
                                                   code,
                                                   NULL,
                                                   0,
                                                   buffer,
                                                   count,
                                                   &bytesReturned,
                                                   NULL);

      if(!retCode)
            return DRV_ERROR_IO;

      return bytesReturned;
}


//Function to do IO operation with the driver, read or write or both
DWORD TDriver::RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;
      bool retCode = DeviceIoControl(driverHandle,
                                                   code,
                                                   inBuffer,
                                                   inCount,
                                                   outBuffer,
                                                   outCount,
                                                   &bytesReturned,
                                                   NULL);

      if(!retCode)
            return DRV_ERROR_IO;

      return bytesReturned;
}
}

0
 
LVL 8

Assisted Solution

by:RomanPetrenko
RomanPetrenko earned 125 total points
ID: 10803989
If you're working with managed c++ why do you use unmanaged types in your LoadDriver function?
use
LoadDriver(String* name, String* path, String* dosName, bool start)
and for calling non-managed code convert this strings to char* with following code:
char* szMessage = (char*)Marshal::StringToHGlobalAnsi(strMessage);
<... Unmanaged call...>
Marshal::FreeHGlobal((int)szMessage);

look here:
Mixing Managed and Unmanaged code
http://www.codeproject.com/dotnet/managed_unmanaged.asp?target=managed%7Ctypes
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
cs.Designer Issue(2) 2 21
c# if statement weird reaction 3 29
VB.NET HttpWebRequest 12 34
Events in static methods 3 27
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now