Solved

LPCTSTR in C#

Posted on 2004-04-09
8
4,434 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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

840 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