Делаю свою API на базе другой API, чтоб воспользоваться из .Net,и структура не заполняется

Дмитрий77
Дата: 25.06.2015 19:32:24
Исходное определение из доков такое:
typedef struct _MODE_STATUS {
    BYTE ModeId;
    bool IsRegistered,
    	 IsKeyPresent,
    	 IsWrongHardwareID,
    	 IsKeyExpired,
    	 IsModeExpired,
    	 IsBlackListedKey,
    	 IsModeActivated;
}MODE_STATUS, *PMODE_STATUS;

 extern "C" BOOL  __stdcall CheckKey( char* Key, char* Name, PMODE_STATUS mode_status );


Я декларирую свою API так
(воспользоваться исходной сразу из .Net не могу, т.к. .Net файлы не прошиваются защитой, при которой исходные API работают)
BOOL __stdcall CPP7_Check_LicenseKey(char* Key, char* Name, PMODE_STATUS ModeStatus)
{ 
  return CheckKey(Key, Name, ModeStatus);
}

Вроде все компилируется.

Использовать пытаюсь так:

 <StructLayout(LayoutKind.Sequential)>
  Public Structure MODE_STATUS
    Dim ModeId As Byte
    Dim IsRegistered As Boolean
    Dim IsKeyPresent As Boolean
    Dim IsWrongHardwareID As Boolean
    Dim IsKeyExpired As Boolean
    Dim IsModeExpired As Boolean
    Dim IsBlackListedKey As Boolean
    Dim IsModeActivated As Boolean
  End Structure

  Public Declare Function CPP7_Check_LicenseKey Lib "License.dll" _
   (ByVal Key As String, ByVal Name As String, ByRef ModeStatus As MODE_STATUS) As Boolean

  Private Sub ButtonCheckKey_Click(sender As Object, e As EventArgs) Handles ButtonCheckKey.Click
    Dim m_ModeStatus As MODE_STATUS
    Dim ValidKey As Boolean
    ValidKey = CPP7_Check_LicenseKey(TextBoxKey.Text, TextBoxName.Text, m_ModeStatus)
    Dim str As String
    str = "ValidKey: " & ValidKey & vbCrLf & _
    "ModeId: " & m_ModeStatus.ModeId & vbCrLf & _
    "IsRegistered: " & m_ModeStatus.IsRegistered & vbCrLf & _
    "IsKeyPresent: " & m_ModeStatus.IsKeyPresent & vbCrLf & _
    "IsWrongHardwareID: " & m_ModeStatus.IsWrongHardwareID & vbCrLf & _
    "IsKeyExpired: " & m_ModeStatus.IsKeyExpired & vbCrLf & _
    "IsModeExpired: " & m_ModeStatus.IsModeExpired & vbCrLf & _
    "IsBlackListedKey: " & m_ModeStatus.IsBlackListedKey & vbCrLf & _
    "IsModeActivated: " & m_ModeStatus.IsModeActivated
    MsgBox(str)
  End Sub


Что получается:
ModeId As Byte -возвращает правильно
Первый Boolean IsRegistered As Boolean -тоже вроде как правильно

А вот остальные Boolean (что ниже первого начиная с IsKeyPresent) -всегда False,
что не соответствует действительности, пробовал генерировать ключи для неправильных HardwareID и с истекшим сроком.

Где накосячил?
Либо PMODE_STATUS на стороне C/C++ не так передаю,
либо со структурой на стороне VB.Net накосячил.

Честно, мне не ясно почему после BYTE ModeId; стоит точка с запятой,
а bool один раз и между остальными параметрами запятые, по идее структуру в VB вроде правильно написал.

М.б. конечно разработчики исходной ф-ции накосячили...
Примеров по этой ф-ции даже для VB6 что-то не видно.
Dimitry Sibiryakov
Дата: 25.06.2015 19:37:35

Дмитрий77
Где накосячил?

Какой размер у Boolean в VB и у bool в С?

Posted via ActualForum NNTP Server 1.5

Дмитрий77
Дата: 25.06.2015 19:39:09
Нашел таки в примерах для VB6 определения:
Public Type TModeStatus
    ModeID               As Byte
    IsRegistered         As Boolean
    IsKeyPresent         As Boolean
    IsWrongHardwareID    As Boolean
    IsKeyExpired         As Boolean
    IsModeExpired        As Boolean
    IsBlackListedKey     As Boolean
    IsModeActivated      As Boolean
End Type

Declare Function apiCheckKey Lib "aspr_ide.dll" Alias "CheckKey" (ByVal Key As String, ByVal Name As String, ByRef ModeStatus As TModeStatus) As Boolean


Так что если где-то и накосячил, то здесь:
BOOL __stdcall CPP7_Check_LicenseKey(char* Key, char* Name, PMODE_STATUS ModeStatus)
{ 
  return CheckKey(Key, Name, ModeStatus);
}


Мож какие * -ки и/ли & -ды для ModeStatus понаставить, туплю(С)
Дмитрий77
Дата: 25.06.2015 19:48:13
Dimitry Sibiryakov
Дмитрий77
Где накосячил?

Какой размер у Boolean в VB и у bool в С?

Намекаешь на то что в C все 7 параметров в единственный байт запихнуты?
Ну, может тогда тупо ByRef все эти 7 параметров возвращать по отдельности, без структуры в VB.Net?
Раскладывая на стороне C?

В .Net наверно как-то можно извернуться, но рука особо не набита.
Dimitry Sibiryakov
Дата: 25.06.2015 19:56:34

Дмитрий77
Намекаешь на то что в C все 7 параметров в единственный байт запихнуты?

Нет, на стороне С они как раз каждый в своём байте. А вот какая двоичная раскладка у твоей
структур в VB - мне неизвестно. Выведи её суммарный размер и сравни с размером этой же
структуры в С.

Posted via ActualForum NNTP Server 1.5

locked
Дата: 25.06.2015 20:20:41
Дмитрий77
Dimitry Sibiryakov
пропущено...

Какой размер у Boolean в VB и у bool в С?

Намекаешь на то что в C все 7 параметров в единственный байт запихнуты?

Намекает на то что размер bool не определен стандартом и зависит от имплементации.
Дмитрий77
Дата: 26.06.2015 01:09:16
Короче вопрос решается на стороне .Net:
  <StructLayout(LayoutKind.Sequential)>
  Public Structure MODE_STATUS
    Dim ModeId As Byte
    <MarshalAs(UnmanagedType.I1)> Dim IsRegistered As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsKeyPresent As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsWrongHardwareID As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsKeyExpired As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsModeExpired As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsBlackListedKey As Boolean
    <MarshalAs(UnmanagedType.I1)> Dim IsModeActivated As Boolean
  End Structure


https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(v=vs.80).aspx

I1 A 1-byte signed integer. You can use this member to transform a Boolean value into a 1-byte, C-style bool (true = 1, false = 0).


Добрый человек подсказал.

Что до VB6 такое по простому видимо не сделаешь, но оно и не надо,
т.к. 1) в VB6 работают исходные API без c-dll (.Net файлы не прошиваются защитой) 2) мне нужен именно .Net
MasterZiv
Дата: 26.06.2015 08:31:49
Dimitry

bool в С нет
Дмитрий77
Дата: 26.06.2015 08:42:46
MasterZiv,

Я не знаю.
Ты ж знаешь что я не спец по вашему языку.

Вот полный файл из AsProtect32 Sky который они дают.
В структуре bool маленькими буквами.
// aspr_api.h : Defines API functions.
//

#ifndef ASPR_API_H
#define ASPR_API_H

// Mode status

typedef struct _MODE_STATUS {
    BYTE ModeId;
    bool IsRegistered,
    	 IsKeyPresent,
    	 IsWrongHardwareID,
    	 IsKeyExpired,
    	 IsModeExpired,
    	 IsBlackListedKey,
    	 IsModeActivated;
}MODE_STATUS, *PMODE_STATUS;

#ifdef __BORLANDC__

 extern "C"  char*   __declspec(dllimport) _stdcall GetRegistrationKeys();
 extern "C" _stdcall __declspec(dllimport) BOOL GetRegistrationInformation( BYTE ModeId, char** Key, char** Name);
 extern "C" _stdcall __declspec(dllimport) BOOL RemoveKey( BYTE ModeId );
 extern "C" _stdcall __declspec(dllimport) BOOL CheckKey( char* Key, char* Name, PMODE_STATUS mode_status );
 extern "C" _stdcall __declspec(dllimport) BOOL CheckKeyAndDecrypt( char* Key, char* Name, BOOL SaveKey );
 extern "C" _stdcall __declspec(dllimport) BOOL GetKeyDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" _stdcall __declspec(dllimport) BOOL GetKeyExpirationDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" _stdcall __declspec(dllimport) BOOL GetTrialDays( BYTE ModeId, DWORD* Total, DWORD* Left );
 extern "C" _stdcall __declspec(dllimport) BOOL GetTrialExecs( BYTE ModeId, DWORD* Total, DWORD* Left );
 extern "C" _stdcall __declspec(dllimport) BOOL GetExpirationDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" _stdcall __declspec(dllimport) BOOL GetModeInformation( BYTE ModeID, char** ModeName, PMODE_STATUS mode_status);
 extern "C"  char*   __declspec(dllimport) _stdcall GetHardwareID();
 extern "C"  char*   __declspec(dllimport) _stdcall GetHardwareIDEx( BYTE ModeID );
 extern "C" _stdcall __declspec(dllimport) BOOL SetUserKey( char* Key, DWORD KeySize );

#else

 extern "C" char* __stdcall GetRegistrationKeys();
 extern "C" BOOL  __stdcall GetRegistrationInformation( BYTE ModeId, char** Key, char** Name);
 extern "C" BOOL  __stdcall RemoveKey( BYTE ModeId );
 extern "C" BOOL  __stdcall CheckKey( char* Key, char* Name, PMODE_STATUS mode_status );
 extern "C" BOOL  __stdcall CheckKeyAndDecrypt( char* Key, char* Name, BOOL SaveKey );
 extern "C" BOOL  __stdcall GetKeyDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" BOOL  __stdcall GetKeyExpirationDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" BOOL  __stdcall GetTrialDays( BYTE ModeId, DWORD* Total, DWORD* Left );
 extern "C" BOOL  __stdcall GetTrialExecs( BYTE ModeId, DWORD* Total, DWORD* Left );
 extern "C" BOOL  __stdcall GetExpirationDate( BYTE ModeId, WORD* Day, WORD* Month, WORD* Year );
 extern "C" BOOL  __stdcall GetModeInformation( BYTE ModeID, char** ModeName, PMODE_STATUS mode_status);
 extern "C" char* __stdcall GetHardwareID();
 extern "C" char* __stdcall GetHardwareIDEx( BYTE ModeID );
 extern "C" BOOL  __stdcall SetUserKey( char* Key, DWORD KeySize );

#endif

#endif


но есть еще
#pragma comment(lib,"include/aspr_ide.lib")

мож оно там где-то сидит.

Короче заработало и чудненько.
egorych
Дата: 26.06.2015 10:52:28
MasterZiv
bool в С нет
есть же, вроде, давно уже ввели.