Как я могу писать в именованный канал в Windows, используя js-ctypes?

Я могу подключиться к каналу (я вижу соединение), но WriteFile всегда дает результат 0, а bytesWritten — 0. Что происходит?

  let pipeName = "\\\\.\\pipe\\xxx.pipe";
  let hFile = createFile(pipeName, pipeMode, 0, null, OPEN_EXISTING, 0, null);
  let hFileInt = ctypes.cast(hFile, ctypes.intptr_t);
  if (ctypes.Int64.compare(hFileInt.value, INVALID_HANDLE_VALUE) == 0) {
    throw new Error("CreateFile failed for " + pipeName + ", error " +
                 ctypes.winLastError);
  }

  let bytesWritten = ctypes.uint32_t(88);
  let msg = "hello world\n";
  let result = writeFile(hFile, msg, 12, bytesWritten.address(), null);
  result = flushFileBuffer(hFile);

результат writeFile равен 0, как и flushFileBuffer, а bytesWritten меняется с 88 на 0. :( Вот объявления:

  let writeFile = kernel32.declare(
    "WriteFile",
    ctypes.winapi_abi,
    ctypes.int32_t,     //bool  // return type: 1 indicates success, 0 failure
    ctypes.voidptr_t,   // in: hObject
    ctypes.jschar.ptr,  // in: lpBuffer
    ctypes.uint32_t,    // in: nNumberOfBytesToWrite
    ctypes.uint32_t.ptr,    // out: lpNumberOfBytesWritten
    ctypes.voidptr_t.ptr    // inout: lpOverlapped
  );  

  let flushFileBuffer = kernel32.declare(
    "FlushFileBuffers",
    ctypes.winapi_abi,
    ctypes.int32_t,     //bool  // return type: 1 indicates success, 0 failure
    ctypes.voidptr_t    // in: hObject
  );

Обновление. Я изменил pipeMode на GENERIC_WRITE и получил успешную запись. Но это сбивает с толку. У меня есть

  var GENERIC_READ = ctypes.uint32_t(0x80000000);
  var GENERIC_WRITE = ctypes.uint32_t(0x40000000);

и

let pipeMode = GENERIC_WRITE;

но

let pipeMode = GENERIC_READ | GENERIC_WRITE;

нет. Почему это не работает? Я неправильно делаю побитовое сравнение?

Обновление 2. pipeMode исправлен с помощью >>> 0

  var GENERIC_READ = 0x80000000;
  var GENERIC_WRITE = 0x40000000;
  let pipeMode = ctypes.uint32_t((GENERIC_READ | GENERIC_WRITE) >>> 0);

Однако это не похоже на то, что канал записывается (даже с флешем), пока я не закрою, используя

  closeHandle(hFile);

и когда дескриптор закрыт, мое принимающее приложение получает сообщение, но это странно. Из моего приложения С# я вижу

h\0e\0l\0l\0l\0o \0

Обновление 3. Из строки C# я ждал целую строку, поэтому ждал \n. Я увеличил длину буфера до 24, и теперь он срабатывает в нужное время. Единственная оставшаяся проблема (для этого вопроса) заключается в том, почему я получаю \0 после каждой буквы.

Обновление 4. Вероятно, проблема в этом.

jschar 16-битный символ без знака. Это отличается от uint16_t тем, что значения C jschar автоматически преобразуются в 1-символьные строки JavaScript. Это символы Юникода.

Я просто хочу обычного персонажа.

Обновление 5. Вот и все. Переход на

ctypes.char.ptr,  // in: lpBuffer

заставляет это работать. Или мы должны учитывать 16-байтовый символ на другой стороне.


person tofutim    schedule 15.03.2016    source источник
comment
Трубки — это то, над чем я давно собирался поработать. Я посмотрю и вернусь к вам сегодня вечером.   -  person Noitidart    schedule 16.03.2016
comment
Теперь каналы работают либо с GENERIC_READ, либо с GENERIC_WRITE — я думаю, что что-то не так с моей побитовой операцией.   -  person tofutim    schedule 16.03.2016
comment
Ваш полный код где-то на github?   -  person Noitidart    schedule 16.03.2016
comment
Для CreateFile ваше значение dwFlagsAndAttributes равно 0, это разрешено?   -  person Noitidart    schedule 16.03.2016
comment
да с этим проблем нет   -  person tofutim    schedule 16.03.2016
comment
У меня есть это в репозитории Bitbucket - завтра проверю, как я могу поделиться.   -  person tofutim    schedule 16.03.2016
comment
Круто, вроде работает. Однако они говорят, что значение 0 недопустимо - stackoverflow.com/a/5926101/1828637   -  person Noitidart    schedule 16.03.2016
comment
Я думаю, мне нужна ваша помощь сейчас, ха-ха, вы знаете, почему я продолжаю получать неверный дескриптор, когда пытаюсь писать/читать из каналов - github.com/Noitidart/jsc-pipes/blob/master/modules/pipe/ — вы можете установить это дополнение, а затем откройте chrome://jsc-pipes/content/pages/gui.xhtml и поиграйте с ним, если хотите - это выглядит так: i.imgur.com/SJ0pE6j. png   -  person Noitidart    schedule 16.03.2016
comment
Я не знаю почему, но когда я пытаюсь CreateFile с dwCreationDisposition как CREATE_NEW, он продолжает выдавать мне ошибку ERROR_FILE_NOT_FOUND, которая ошеломляет, потому что она явно не будет найдена, она не существует, я хочу, чтобы она это сделала. Вы знаете, что случилось?   -  person Noitidart    schedule 16.03.2016
comment
Ааа, вы не можете CREATE_NEW канал с CreateFile, вам пришлось бы использовать CreateNamedPIpe, и это стало бы сервером именованного канала. В другой программе я вызываю CreateNamedPipe, а из javascript я вызываю CreateFile OPEN_EXISTING.   -  person tofutim    schedule 16.03.2016
comment
@Noitidart, у тебя есть имя пользователя Bitbucket?   -  person tofutim    schedule 16.03.2016
comment
@Noitidart - readFile - stackoverflow.com/questions/36031573/   -  person tofutim    schedule 16.03.2016
comment
Большое спасибо за информацию о CreateNamedPipe! Я обновлю это до завтра. Я проверил этот файл для чтения и, похоже, вы его поняли! я тоже такой, когда я объясняю свой вопрос о stackoverflow, я в конце концов решаю его, ха-ха, хотя я прошу продолжать работать над ним. :) Хорошая работа! :) Вы должны поместить свой ответ на этот вопрос в решение, приятно видеть ответы на все вопросы в разделе: P   -  person Noitidart    schedule 16.03.2016
comment
у вас есть код, который вы можете показать, где вы делаете CreateNamedPipe? Я настраиваю файловый наблюдатель. Основной поток создает канал, а дочерний поток является опрашивающим. Я хочу, чтобы опросчик ломался, когда я отправляю сообщение по каналу. Любой код, которым вы могли бы поделиться, помог бы тоннам, спасибо!   -  person Noitidart    schedule 15.07.2016