Node-SMB / marsaud-smb2

SMB2 Client
53 stars 46 forks source link

Error: STATUS_PENDING #78

Open caocong1 opened 3 years ago

caocong1 commented 3 years ago
const SMB2 = require('@marsaud/smb2');
const fs =require("fs");

const smb2Client = new SMB2({
    share: `\\\\000.000.000.000\\project`,
    domain: 'DOMAIN',
    username: 'username',
    password: 'password',
});

smb2Client.createWriteStream('personal\\test10k.txt', function(err, writeStream) {
    if (err) throw err;
    const readStream = fs.createReadStream('/home/caocong/test10k.txt');
    readStream.pipe(writeStream);
});
/usr/bin/node /home/caocong/workspace/test/index.js
node:events:342
      throw er; // Unhandled 'error' event
      ^

Error: STATUS_PENDING (0x00000103) : The operation that was requested is pending completion.
    at SMB2Forge.request (/home/caocong/workspace/test/node_modules/@marsaud/smb2/lib/tools/smb2-forge.js:22:15)
    at Writable.stream._destroy (/home/caocong/workspace/test/node_modules/@marsaud/smb2/lib/api/createWriteStream.js:55:9)
    at _destroy (node:internal/streams/destroy:72:23)
    at Writable.destroy (node:internal/streams/destroy:64:5)
    at Writable.destroy (node:internal/streams/writable:861:11)
    at errorOrDestroy (node:internal/streams/destroy:242:12)
    at onwriteError (node:internal/streams/writable:422:3)
    at onwrite (node:internal/streams/writable:457:7)
    at /home/caocong/workspace/test/node_modules/@marsaud/smb2/lib/api/createWriteStream.js:40:20
    at Object.<anonymous> (/home/caocong/workspace/test/node_modules/@marsaud/smb2/lib/tools/message.js:19:15)
Emitted 'error' event on Writable instance at:
    at Writable.onerror (node:internal/streams/readable:770:14)
    at Writable.emit (node:events:365:28)
    at emitErrorNT (node:internal/streams/destroy:193:8)
    at emitErrorCloseNT (node:internal/streams/destroy:158:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  messageName: 'close',
  params: {
    StructureSize: Buffer(2) [Uint8Array] [ 89, 0 ],
    OplockLevel: Buffer(1) [Uint8Array] [ 0 ],
    Flags: Buffer(1) [Uint8Array] [ 0 ],
    CreateAction: Buffer(4) [Uint8Array] [ 2, 0, 0, 0 ],
    CreationTime: Buffer(8) [Uint8Array] [
      24, 65, 188, 85,
      11, 86, 215,  1
    ],
    LastAccessTime: Buffer(8) [Uint8Array] [
      24, 65, 188, 85,
      11, 86, 215,  1
    ],
    LastWriteTime: Buffer(8) [Uint8Array] [
      24, 65, 188, 85,
      11, 86, 215,  1
    ],
    ChangeTime: Buffer(8) [Uint8Array] [
      24, 65, 188, 85,
      11, 86, 215,  1
    ],
    AllocationSize: Buffer(8) [Uint8Array] [
      0, 0, 0, 0,
      0, 0, 0, 0
    ],
    EndofFile: Buffer(8) [Uint8Array] [
      0, 0, 0, 0,
      0, 0, 0, 0
    ],
    FileAttributes: Buffer(4) [Uint8Array] [ 32, 0, 0, 0 ],
    Reserved2: Buffer(4) [Uint8Array] [ 0, 0, 0, 0 ],
    FileId: Buffer(16) [Uint8Array] [
      199, 131, 249, 165,   0,  0,
        0,   0, 117,  59, 179, 28,
        0,   0,   0,   0
    ],
    CreateContextsOffset: Buffer(4) [Uint8Array] [ 0, 0, 0, 0 ],
    CreateContextsLength: Buffer(4) [Uint8Array] [ 0, 0, 0, 0 ],
    Buffer: Buffer(0) [Uint8Array] []
  },
  code: 'STATUS_PENDING'
}

I found out the reason is async request. But I don't know how to do.

matteolel commented 3 years ago

I've got the same issue, but reading a file.


    var smb2Client = new SMB2({
        share: '\\\\my-server\\public-share'
        , domain: ''
        , username: ''
        , password: ''
    });

    // existance
    const appl = await new Promise((res, rej) => {
        smb2Client.exists('my-file', function (err, exists) {
            if (err) throw err;
            debug(exists);
            res(exists);
        });
    });
    if (!appl) {
        console.error("my-file doesn't exist");
        process.exit(1);
    }
    // appl is true also when error is thrown!
    const applFile = await new Promise((res, rej) => {
        smb2Client.readFile('my-file', { encoding: null }, function (err, data) {
            if (err) throw err;  <-- error here
            debug(data.length);
            debug(data);
            res(data); 
        });
    });
    fs.writeFileSync(path.join(tempFolder, "my-file"), applFile);
Error: STATUS_PENDING (0x00000103) : The operation that was requested is pending completion.
    at SMB2Forge.request (/home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/tools/smb2-forge.js:22:15)
    at createPackets (/home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/api/readFile.js:79:11)
    at checkDone (/home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/api/readFile.js:57:9)
    at /home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/api/readFile.js:50:13
    at Object.<anonymous> (/home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/tools/message.js:15:15)
    at Socket.<anonymous> (/home/dl.net_mlelli/dev/repos/image-accelerator/node_modules/@marsaud/smb2/lib/tools/smb2-forge.js:71:31)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at Socket.Readable.push (internal/streams/readable.js:223:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
  messageName: 'read',
  params: {
    FileId: Buffer(16) [Uint8Array] [
      64, 54, 190, 186,   0,   0,
       0,  0,  99, 231, 127, 125,
       0,  0,   0,   0
    ],
    Length: 65536,
    Offset: Buffer(8) [Uint8Array] [
      0, 0, 150, 0,
      0, 0,   0, 0
    ]
  },
  code: 'STATUS_PENDING'
}
efreibe commented 1 year ago

I've resolved with a hack, I don't sure if this is the right way to do it but maybe could help to resolve the problem.

SMB2Forge.response = function (c) {
  c.responses = {}
  c.responsesCB = {}
  c.responseBuffer = Buffer.allocUnsafe(0)
  return function (response) {
    // concat new response
    c.responseBuffer = Buffer.concat([c.responseBuffer, response])
    // extract complete messages
    var extract = true
    while (extract) {
      extract = false
      // has a message header
      if (c.responseBuffer.length >= 4) {
        // message is complete
        var msgLength = (c.responseBuffer.readUInt8(1) << 16) + c.responseBuffer.readUInt16BE(2)
        if (c.responseBuffer.length >= msgLength + 4) {
          // set the flags
          extract = true
          // parse message
          var r = c.responseBuffer.slice(4, msgLength + 4)
          var message = new SMB2Message()
          message.parseBuffer(r)
          // debug
          if (c.debug) {
            console.log('--response') // eslint-disable-line no-console
            console.log(r.toString('hex')) // eslint-disable-line no-console
          }
          // get the message id
          var mId = message.getHeaders().MessageId.toString('hex')
          // check if the message can be dispatched
          // or store it
          if (c.responsesCB[mId]) {
            const Status = message.getHeaders().Status.toString('hex')
            // Check the error, in case of STATUS_PENDING skip the parsing function
            if (Status != '03010000') {
              c.responsesCB[mId](message)
              delete c.responsesCB[mId]
            }
          } else {
            c.responses[mId] = message
          }
          // remove from response buffer
          c.responseBuffer = c.responseBuffer.slice(msgLength + 4)
        }
      }
    }
  }
}
twister36 commented 8 months ago

I agree, it appears that this node has issues being executed multiple times, while it's still in use. Therefore I added a delay node before it and change the delay node to limit the rate of messages of 1 per second. Not thrilled that I have to cause a delay, but it works for now.