Функция Windows API WriteFile() приводит к краху МТ4.

 

Вот такая функция приводит к краху МТ4:

int CreateFileStringValue (string& PathName, // Название файла.
                           string& Value,    // Переменная для записи.
                           int&    Size,     // Длина записываемой строки.
                           int&    Offset,   // Смещение в байтах файлового указателя.
                           int&    Origin)   // Начальное положение файлового указателя (величина может быть одной из этих констант: SEEK_CUR - от текущего положения,
                                             //                                                                                      SEEK_SET - от начала,
                                             //                                                                                      SEEK_END - от конца файла).
 {
  int    Return = -1;
  int    Handle = CreateFileA (PathName, FILE_WRITE_DATA, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // Создаём файл.
  //----
  if (Handle == -1)
   {
    Print ("Ошибка в функции \"CreateFileStringValue()\". Файл с путём \"", PathName, "\" не создан.");
    return (false);
   }
  else // Если файл открыт, сдвигаем файловый указатель, куда требуется.
   {
    if (SetFilePointer (Handle, Offset, NULL, Origin) == -1)
     {
      Print ("Ошибка в функции \"CreateFileStringValue()\". Файловый указатель файла с путём \"", PathName, "\" не смещён.");
      if (CloseHandle (Handle) == false) Print ("Ошибка в функции \"CreateFileStringValue()\". Файл с путём \"", PathName, "\" не закрыт.");
      return (-1);
     }
    // Записываем в файл входное значение.
//    if (_lwrite (Handle, Value, Size) == -1) Print ("Ошибка в функции \"CreateFileStringValue()\". Значение в файл с путём \"", PathName, "\" не записано.");
    if (WriteFile (Handle, Value, Size, Return, NULL) == false) Print ("Ошибка в функции \"CreateFileStringValue()\". Значение в файл с путём \"", PathName, "\" не записано.");
    if (CloseHandle (Handle) == false) // Закрываем файл.
     {
      Print ("Ошибка в функции \"CreateFileStringValue()\". Файл с путём \"", PathName, "\" не закрыт.");
      return (-1);
     }
   }
  return (Return);
 }

Если заменить WriteFile() на _lwrite(), то всё работает.

Кто знает в чём дело? Вот лог краха:

There has been a critical error
Time : 2008.10.05 04:06
Program : Client Terminal
Version : 4.00 (build: 218, 26 Aug 2008)
OS : Windows XP Professional 5.1 Service Pack 3 (Build 2600)
Processors : 1 x X86 (level 6)
Memory : 2096432/1299852 kb
Exception : C0000005
Address : 7C810E2C
Access Type : read
Access Addr : FFFFFFFF

Registers : EAX=0308FA24 CS=001b EIP=7C810E2C EFLGS=00010286
  : EBX=FFFFFFFF SS=0023 ESP=0308FA00 EBP=0308FA34
  : ECX=00000000 DS=0023 ESI=01C2B008 FS=003b
  : EDX=01C98E10 ES=0023 EDI=0000015C GS=0000

Stack Trace : 0045814E 00463707 00000000 00000000
  : 00000000 00000000 00000000 00000000
  : 00000000 00000000 00000000 00000000
  : 00000000 00000000 00000000 00000000

Modules :
  1 : 00400000 007F5194 e:\market\forex\Брокеры\alpari-idc\metatrader - alpari 4.00\terminal.exe
  2 : 01FA0000 002CD000 c:\windows\system32\xpsp2res.dll
  3 : 08000000 00008000 e:\tools\tuning windows\tweackers\punto switcher 2.96\pshook.dll.1215800446
  4 : 10000000 00055000 e:\guard\firewall\outpost firewall pro 4.0\wl_hook.dll
  5 : 5B260000 00038000 c:\windows\system32\uxtheme.dll
  6 : 61EC0000 0000E000 c:\windows\system32\mfc42loc.dll
  7 : 65780000 00023000 c:\program files\avast 4.8 pro\ahjsctns.dll
  8 : 698B0000 00058000 c:\windows\system32\hnetcfg.dll
  9 : 71A30000 00040000 c:\windows\system32\mswsock.dll
  10 : 71A70000 00008000 c:\windows\system32\wshtcpip.dll
  11 : 71A80000 00008000 c:\windows\system32\ws2help.dll
  12 : 71A90000 00017000 c:\windows\system32\ws2_32.dll
  13 : 72CD0000 00008000 c:\windows\system32\msacm32.drv
  14 : 72CE0000 00009000 c:\windows\system32\wdmaud.drv
  15 : 73D90000 000FE000 c:\windows\system32\mfc42.dll
  16 : 746E0000 0004C000 c:\windows\system32\msctf.dll
  17 : 75310000 0002E000 c:\windows\system32\msctfime.ime
  18 : 76350000 00005000 c:\windows\system32\msimg32.dll
  19 : 76360000 0001D000 c:\windows\system32\imm32.dll
  20 : 76380000 00049000 c:\windows\system32\comdlg32.dll
  21 : 76B20000 0002E000 c:\windows\system32\winmm.dll
  22 : 76C20000 0002E000 c:\windows\system32\wintrust.dll
  23 : 76C80000 00028000 c:\windows\system32\imagehlp.dll
  24 : 76F10000 00027000 c:\windows\system32\dnsapi.dll
  25 : 76F50000 0002D000 c:\windows\system32\wldap32.dll
  26 : 76FA0000 00008000 c:\windows\system32\winrnr.dll
  27 : 76FB0000 00006000 c:\windows\system32\rasadhlp.dll
  28 : 77110000 0008B000 c:\windows\system32\oleaut32.dll
  29 : 773C0000 00103000 c:\windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll
  30 : 774D0000 0013D000 c:\windows\system32\ole32.dll
  31 : 77A70000 00096000 c:\windows\system32\crypt32.dll
  32 : 77B10000 00012000 c:\windows\system32\msasn1.dll
  33 : 77BC0000 00007000 c:\windows\system32\midimap.dll
  34 : 77BD0000 00015000 c:\windows\system32\msacm32.dll
  35 : 77C00000 00058000 c:\windows\system32\msvcrt.dll
  36 : 77DC0000 000AC000 c:\windows\system32\advapi32.dll
  37 : 77E70000 00092000 c:\windows\system32\rpcrt4.dll
  38 : 77F10000 00049000 c:\windows\system32\gdi32.dll
  39 : 77F60000 00076000 c:\windows\system32\shlwapi.dll
  40 : 77FE0000 00011000 c:\windows\system32\secur32.dll
  41 : 7C800000 000F8000 c:\windows\system32\kernel32.dll
  42 : 7C900000 000B0000 c:\windows\system32\ntdll.dll
  43 : 7C9C0000 0086F000 c:\windows\system32\shell32.dll
  44 : 7E360000 00091000 c:\windows\system32\user32.dll

Call stack :
00457AA0:06AE [0045814E] ?CallDllFunction@CExpertInterior (terminal.exe)
0045F8B0:3E57 [00463707] ?ExecuteStaticAsm@CExpertInterior (terminal.exe)

 

Функция WriteFile() возвращает количество записанных байт через указатель.

Поэтому в директиве #import  функцию необходимо объявить следующим образом:

#import "kernel32.dll"
   bool WriteFile(int hFile, string lpBuffer,int nNumberOfBytesToWrite,int& lpNumberOfBytesWritten[],int lpOverlapped);
#import
Затем перед вызывом функции переменную для возврата количества записанных байт (lpNumberOfBytesWritten) в коде объявляете так:
int Return[1];

Инициализировать её необязательно.

Вызов функции в коде оставляете без изменений.

 

Ilnur, Вы очередной раз спасаете.

Спасибо! Всё теперь работает!

====================

Есть ещё один вопрос. Почему функция "CreateFileA()" при указанных атрибутах не перезаписывает файл? Должна перезаписывать, а она дописывает.

 
Zhunko >>:

. . .

Есть ещё один вопрос. Почему функция "CreateFileA()" при указанных атрибутах не перезаписывает файл? Должна перезаписывать, а она дописывает.

Вы не правильно определяете тип доступа к файлу.

Вот примеры вызова функции для различных типов доступа к файлу:

#define GENERIC_READ      0x80000000
#define GENERIC_WRITE     0x40000000

#define FILE_SHARE_READ   1  
#define FILE_SHARE_WRITE  2

#define CREATE_ALWAYS     2
#define OPEN_EXISTING     3

//Открытие (создание) файла для записи
CreateFileA(PathName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,CREATE_ALWAYS,0,0);

//Открытие файла для чтения
CreateFileA(PathName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);

//Открытие файла для добавления новых данных
CreateFileA(PathName,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
 

Спасибо!

Откуда Вы взяли значения этих констант:

#define GENERIC_READ      0x80000000
#define GENERIC_WRITE     0x40000000
Долго искал и не нашёл. Ссылку дадите на MSDN?

В MSDN для функции "CreateFile()" не нашёл. А из того, что прочитал, понял, что надо комбинировать эти константы:

#define FILE_ADD_FILE                0x0002
#define FILE_ADD_SUBDIRECTORY        0x0004
#define FILE_ALL_ACCESS
#define FILE_APPEND_DATA             0x0004
#define FILE_CREATE_PIPE_INSTANCE    0x0004
#define FILE_DELETE_CHILD            0x0040
#define FILE_EXECUTE                 0x0020
#define FILE_LIST_DIRECTORY          0x0001
#define FILE_READ_ATTRIBUTES         0x0080
#define FILE_READ_DATA               0x0001
#define FILE_READ_EA                 0x0008
#define FILE_TRAVERSE                0x0020
#define FILE_WRITE_ATTRIBUTES        0x0100
#define FILE_WRITE_DATA              0x0002
#define FILE_WRITE_EA                0x0010
#define STANDARD_RIGHTS_READ
#define STANDARD_RIGHTS_WRITE
#define SYNCHRONIZE

При чём, у четырёх нет значений. Наверно забыли написать. Если это не так, то зачем они?
Может их можно комбинировать для уточнения операции? Например:

GENERIC_WRITE | FILE_APPEND_DATA
Обязательно ли комбинировать для чтения так:
FILE_SHARE_READ|FILE_SHARE_WRITE
 
Zhunko >>:

Спасибо!

Откуда Вы взяли значения этих констант:

Долго искал и не нашёл. Ссылку дадите на MSDN?

В MSDN для функции "CreateFile()" не нашёл. А того, что прочитал, понял, что надо комбинировать эти константы:

Почитайте здесь

Обязательно ли комбинировать для чтения так:

Нет. Но таким макаром мы позволяем другим процессам обращаться к файлу. Читать там же.

 
TheXpert >>:
Почитайте здесь

Нет. Но таким макаром мы позволяем другим процессам обращаться к файлу. Читать там же.

Все мои знания именно с этой ссылки. Там ни чего нового со вчера не появилось.

 
Zhunko >>:

Все мои знания именно с этой ссылки. Там ни чего нового со вчера не появилось.

Оо. Тогда я честно не понимаю. Так написано гораздо больше чем скажут Вам здесь. И константы в том числе.

Самое главное умение кодера -- это умение пользоваться мануалом.

 
Zhunko >>:

Спасибо!
Откуда Вы взяли значения этих констант:

#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000

Значения констант для WinAPI функций я беру из заголовочных файлов (*.h) пакета Microsoft SDKs. Он установлен у меня вместе с Microsoft Visual Studio.

К примеру эти константы объявлены в файле winnt.h.


Ссылку дадите на MSDN?

Я пользуюсь MSDN из пакета Microsoft Visual Studio.

 
Ilnur >>:

Значения констант для WinAPI функций я беру из заголовочных файлов (*.h) пакета Microsoft SDKs. Он установлен у меня вместе с Microsoft Visual Studio.

К примеру эти константы объявлены в файле winnt.h.

Я пользуюсь MSDN из пакета Microsoft Visual Studio.

Понятно. Систему переустановил и всё ни, как не соберусь Visual Studio поставить. Говорят вот-вот русская выйдет. Не тороплюсь.

MSDN из пакета и с сайта разные по объёму? Какой пополняется быстрее и является более полным?

 
Zhunko >>:

Понятно. Систему переустановил и всё ни, как не соберусь Visual Studio поставить. Говорят вот-вот русская выйдет. Не тороплюсь.

MSDN из пакета и с сайта разные по объёму? Какой пополняется быстрее и является более полным?

Не знаю никогда не сравнивал.

Мне всегда было достаточно MSDN`а, который входит в состав Visual Studio.

Причина обращения: