local os = require "os"
local stdnse = require "stdnse"
local string = require "string"
local stringaux = require "stringaux"
local table = require "table"
local unicode = require "unicode"
_ENV = stdnse.module("msrpctypes", stdnse.seeall)
local REFERENT_ID = 0x50414d4e
local HEAD = 'HEAD'
local BODY = 'BODY'
local ALL  = 'ALL'
function string_to_unicode(string, do_null)
  local i
  stdnse.debug4("MSRPC: Entering string_to_unicode(string = %s)", string)
  if(do_null == nil) then
    do_null = false
  end
  if(type(string) ~= 'string') then
    string = tostring(string)
  end
  if(string == nil) then
    stdnse.debug1("MSRPC: WARNING: couldn't convert value to string in string_to_unicode()")
  end
  local result = unicode.utf8to16(string)
  if(do_null == true) then
    result = result .. "\0\0"
  end
  if(#result % 4 ~= 0) then
    result = result .. "\0\0"
  end
  stdnse.debug4("MSRPC: Leaving string_to_unicode()")
  return result
end
function unicode_to_string(buffer, pos, length, do_null)
  stdnse.debug4("MSRPC: Entering unicode_to_string(pos = %d, length = %d)", pos, length)
  local endpos = pos + length * 2 - 1
  if endpos > #buffer then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a string in unicode_to_string(), this likely means we are reading a packet incorrectly. Please report! (pos = %d, #buffer = %d, endpos = %d)", pos, #buffer, endpos)
    return nil, nil
  end
  local str = unicode.utf16to8(string.sub(buffer, pos, endpos))
  if do_null then
    str = string.sub(str, 1, -2) -- Eat the null terminator
  end
  endpos = endpos + (endpos + 1 - pos) % 4
  stdnse.debug4("MSRPC: Leaving unicode_to_string()")
  return endpos + 1, str
end
local function marshall_ptr(location, func, args, value)
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_ptr(location = %s)", location)
  if(location == HEAD or location == ALL) then
    if(func == nil or args == nil or value == nil) then
      result = result .. string.pack("<I4", 0)
    else
      result = result .. string.pack("<I4", REFERENT_ID)
    end
  end
  if(location == BODY or location == ALL) then
    if(func == nil or args == nil or value == nil) then
    else
      result = result .. func(table.unpack(args))
    end
  end
  stdnse.debug4("MSRPC: Leaving marshall_ptr()")
  return result
end
local function unmarshall_ptr(location, data, pos, func, args, result)
  stdnse.debug4("MSRPC: Entering unmarshall_ptr()")
  if(args == nil) then
    args = {}
  end
  if(location == HEAD or location == ALL) then
    if #data - pos + 1 < 4 then
      stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_ptr(). Please report!")
      return pos, nil
    end
    local referent_id
    referent_id, pos = string.unpack("<I4", data, pos)
    if(location == HEAD) then
      if(referent_id == 0) then
        result = false
      else
        result = true
      end
    else
      if(referent_id == 0) then
        result = nil
      else
        result = true
      end
    end
  end
  if(location == BODY or location == ALL) then
    if(result == true) then
      pos, result = func(data, pos, table.unpack(args))
    else
      result = nil
    end
  end
  return pos, result
end
local function marshall_basetype(location, func, args)
  local result
  stdnse.debug4("MSRPC: Entering marshall_basetype()")
  if(location == HEAD or location == ALL) then
    result = func(table.unpack(args))
  else
    result = ""
  end
  stdnse.debug4("MSRPC: Leaving marshall_basetype()")
  return result
end
function marshall_array(array)
  stdnse.debug4("MSRPC: Entering marshall_array()")
  local result = {string.pack("<I4", #array)}
  for i = 1, #array, 1 do
    local func = array[i]['func']
    local args = array[i]['args']
    result[#result+1] = func(HEAD, table.unpack(args))
  end
  for i = 1, #array, 1 do
    local func = array[i]['func']
    local args = array[i]['args']
    result[#result+1] = func(BODY, table.unpack(args))
  end
  stdnse.debug4("MSRPC: Leaving marshall_array()")
  return table.concat(result)
end
local function unmarshall_array(data, pos, count, func, args)
  stdnse.debug4("MSRPC: Entering unmarshall_array()")
  if(args == nil) then
    args = {}
  end
  if #data - pos + 1 < 4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_array(). Please report!")
    return pos, nil
  end
  local max_count, pos = string.unpack("<I4", data, pos)
  local result = {}
  for i = 1, count, 1 do
    pos, result[i] = func(HEAD, data, pos, nil, table.unpack(args))
  end
  for i = 1, count, 1 do
    pos, result[i] = func(BODY, data, pos, result[i], table.unpack(args))
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_array()")
  return pos, result
end
local function unmarshall_struct(data, pos, func, args)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_struct()")
  if(args == nil) then
    args = {}
  end
  pos, result = func(ALL, data, pos, nil, args)
  stdnse.debug4("MSRPC: Leaving unmarshall_struct()")
  return pos, result
end
function marshall_unicode(str, do_null, max_length)
  local buffer_length
  local result
  stdnse.debug4("MSRPC: Entering marshall_unicode()")
  if(do_null == nil) then
    do_null = false
  end
  if(do_null) then
    buffer_length = #str + 1
  else
    buffer_length = #str
  end
  if(max_length == nil) then
    max_length = buffer_length
  end
  result = string.pack("<I4I4I4",
    max_length,       -- Max count
    0,                -- Offset
    buffer_length)   -- Actual count
    .. string_to_unicode(str, do_null, true)
  stdnse.debug4("MSRPC: Leaving marshall_unicode()")
  return result
end
function marshall_ascii(str, max_length)
  local buffer_length
  local result
  buffer_length = #str + 1
  if(max_length == nil) then
    max_length = buffer_length
  end
  local padding = string.rep('\0', (4 - (buffer_length % 4)) % 4)
  result = string.pack("<I4I4I4z",
    max_length,
    0,
    buffer_length,
    str)
    .. padding
  return result
end
function marshall_unicode_ptr(str, do_null, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_unicode()")
  result = marshall_ptr(ALL, marshall_unicode, {str, do_null, max_length}, str)
  stdnse.debug4("MSRPC: Leaving marshall_unicode()")
  return result
end
function marshall_ascii_ptr(str, max_length)
  local result
  result = marshall_ptr(ALL, marshall_ascii, {str, max_length}, str)
  return result
end
function unmarshall_unicode(data, pos, do_null)
  local ptr, str
  local max, offset, actual
  stdnse.debug4("MSRPC: Entering unmarshall_unicode()")
  if(do_null == nil) then
    do_null = false
  end
  if #data - pos + 1 < 3*4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_unicode(). Please report!")
    return pos, nil
  end
  max, offset, actual, pos = string.unpack("<I4I4I4", data, pos)
  pos, str = unicode_to_string(data, pos, actual, do_null, true)
  stdnse.debug4("MSRPC: Leaving unmarshall_unicode()")
  return pos, str
end
function unmarshall_unicode_ptr(data, pos, do_null)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_unicode_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_unicode, {do_null})
  stdnse.debug4("MSRPC: Leaving unmarshall_unicode_ptr()")
  return pos, result
end
function marshall_unicode_array(strings, do_null)
  local array = {}
  local result
  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_ptr
    array[i]['args'] = {marshall_unicode, {strings[i], do_null}, strings[i]}
  end
  result = marshall_array(array)
  return result
end
function marshall_unicode_array_ptr(strings, do_null)
  local result
  result = marshall_ptr(ALL, marshall_unicode_array, {strings, do_null}, strings)
  return result
end
function marshall_int64(int64)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int64()")
  result = string.pack("<I8", int64)
  stdnse.debug4("MSRPC: Leaving marshall_int64()")
  return result
end
function marshall_int32(int32)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int32()")
  result = string.pack("<I4", int32)
  stdnse.debug4("MSRPC: Leaving marshall_int32()")
  return result
end
function marshall_int32_array(data)
  local result = {
    marshall_int32(0x0400), -- Max count
    marshall_int32(0),     -- Offset
    marshall_int32(#data), -- Actual count
  }
  for _, v in ipairs(data) do
    result[#result+1] = marshall_int32(v)
  end
  return table.concat(result)
end
function marshall_int16(int16, pad)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int16()")
  if(pad == false) then
    return string.pack("<I2", int16)
  end
  result = string.pack("<I2xx", int16)
  stdnse.debug4("MSRPC: Leaving marshall_int16()")
  return result
end
function marshall_int8(int8, pad)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int8()")
  if(pad == false) then
    return string.pack("<B", int8)
  end
  result = string.pack("<Bxxx", int8)
  stdnse.debug4("MSRPC: Leaving marshall_int8()")
  return result
end
function unmarshall_int64(data, pos)
  local value
  stdnse.debug4("MSRPC: Entering unmarshall_int64()")
  if #data - pos + 1 < 8 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int64(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<i8", data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_int64()")
  return pos, value
end
function unmarshall_int32(data, pos)
  local value
  if #data - pos + 1 < 4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int32(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<I4", data, pos)
  return pos, value
end
function unmarshall_int16(data, pos, pad)
  local value
  stdnse.debug4("MSRPC: Entering unmarshall_int16()")
  if #data - pos + 1 < 2 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int16(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<I2", data, pos)
  if(pad == nil or pad == true) then
    pos = pos + 2
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_int16()")
  return pos, value
end
function unmarshall_int8(data, pos, pad)
  local value
  stdnse.debug4("MSRPC: Entering unmarshall_int8()")
  if #data - pos + 1 < 1 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<B", data, pos)
  if(pad == nil or pad == true) then
    pos = pos + 3
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_int8()")
  return pos, value
end
function marshall_int64_ptr(int64)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int64_ptr()")
  result = marshall_ptr(ALL, marshall_int64, {int64}, int64)
  stdnse.debug4("MSRPC: Leaving marshall_int64_ptr()")
  return result
end
function marshall_int32_ptr(int32)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int32_ptr()")
  result = marshall_ptr(ALL, marshall_int32, {int32}, int32)
  stdnse.debug4("MSRPC: Leaving marshall_int32_ptr()")
  return result
end
function marshall_int16_ptr(int16, pad)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int16_ptr()")
  result = marshall_ptr(ALL, marshall_int16, {int16, pad}, int16)
  stdnse.debug4("MSRPC: Leaving marshall_int16_ptr()")
  return result
end
function marshall_int8_ptr(int8, pad)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int8_ptr()")
  result = marshall_ptr(ALL, marshall_int8, {int8, pad}, int8)
  stdnse.debug4("MSRPC: Leaving marshall_int8_ptr()")
  return result
end
function unmarshall_int32_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_int32_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int32, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_int32_ptr()")
  return pos, result
end
function unmarshall_int16_ptr(data, pos, pad)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_int16_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int16, {pad})
  stdnse.debug4("MSRPC: Leaving unmarshall_int16_ptr()")
  return pos, result
end
function unmarshall_int8_ptr(data, pos, pad)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_int8_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int8, {pad})
  stdnse.debug4("MSRPC: Leaving unmarshall_int8_ptr()")
  return pos, result
end
function marshall_int8_array(data, max_length)
  stdnse.debug4("MSRPC: Entering marshall_int8_array()")
  if(max_length == nil) then
    max_length = #data
  end
  local result = string.pack("<I4I4", max_length, 0) .. data
  stdnse.debug4("MSRPC: Leaving marshall_int8_array()")
  return result
end
function unmarshall_int8_array(data, pos, pad)
  local max, offset, actual
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_int8_array()")
  if #data - pos + 1 < 3*4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8_array(). Please report!")
    return pos, nil
  end
  max, offset, actual, pos = string.unpack("<I4I4I4", data, pos)
  if #data - pos + 1 < actual then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8_array() [2]. Please report!")
    return pos - 3*4, nil
  end
  str, pos = string.unpack("<c"..actual, data, pos)
  if(pad == nil or pad == true) then
    while(((pos - 1) % 4) ~= 0) do
      pos = pos + 1
    end
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_int8_array()")
  return pos, str
end
function marshall_int8_array_ptr(data, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int8_array_ptr()")
  result = marshall_ptr(ALL, marshall_int8_array, {data, max_length}, data)
  stdnse.debug4("MSRPC: Leaving marshall_int8_array_ptr()")
  return result
end
function unmarshall_int8_array_ptr(data, pos, pad)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_int8_array_ptr()")
  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_int8_array, {pad})
  stdnse.debug4("MSRPC: Leaving unmarshall_int8_array_ptr()")
  return pos, str
end
function unmarshall_int32_array(data, pos, count)
  local maxcount
  local result = {}
  pos, maxcount = unmarshall_int32(data, pos)
  for i = 1, count, 1 do
    pos, result[i] = unmarshall_int32(data, pos)
  end
  return pos, result
end
function unmarshall_int32_array_ptr(data, pos)
  local count, array
  pos, count = unmarshall_int32(data, pos)
  pos, array = unmarshall_ptr(ALL, data, pos, unmarshall_int32_array, {count})
  return pos, array
end
function marshall_NTTIME(time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_NTTIME()")
  if(time == 0) then
    result = string.pack("<I8", 0)
  else
    result = string.pack("<I8", (time + 11644473600) * 10000000)
  end
  stdnse.debug4("MSRPC: Leaving marshall_NTTIME()")
  return result
end
function unmarshall_NTTIME(data, pos)
  local time
  stdnse.debug4("MSRPC: Entering unmarshall_NTTIME()")
  if #data - pos + 1 < 8 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_NTTIME(). Please report!")
    return pos, nil
  end
  time, pos = string.unpack("<I8", data, pos)
  if(time ~= 0) then
    time = (time // 10000000) - 11644473600
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_NTTIME()")
  return pos, time
end
function marshall_NTTIME_ptr(time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_NTTIME_ptr()")
  result = marshall_ptr(ALL, marshall_NTTIME, {time}, time)
  stdnse.debug4("MSRPC: Leaving marshall_NTTIME_ptr()")
  return result
end
function unmarshall_NTTIME_ptr(data, pos)
  local time
  stdnse.debug4("MSRPC: Entering unmarshall_NTTIME_ptr()")
  pos, time = unmarshall_ptr(ALL, data, pos, unmarshall_NTTIME, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_NTTIME_ptr()")
  return pos, time
end
function unmarshall_SYSTEMTIME(data, pos)
  local fmt = "<I2I2I2I2I2I2I2I2"
  if #data - pos + 1 < string.packsize(fmt) then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_SYSTEMTIME(). Please report!")
    return pos, nil
  end
  local date = {}
  date.year, date.month, date.dow, date.day, date.hour, date.min, date.sec, date.msec, pos = string.unpack(fmt, data, pos)
  return pos, os.time(date)
end
function unmarshall_hyper(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_hyper()")
  pos, result = unmarshall_int64(data, pos)
  result = result // -10000000
  stdnse.debug4("MSRPC: Leaving unmarshall_hyper()")
  return pos, result
end
local function marshall_Enum32(val, table)
  local result = 0
  stdnse.debug4("MSRPC: Entering marshall_Enum32()")
  local vals = stringaux.strsplit("|", val)
  local i
  for i = 1, #vals, 1 do
    result = result | table[vals[i]]
  end
  result = marshall_int32(result)
  stdnse.debug4("MSRPC: Leaving marshall_Enum32()")
  return result
end
local function unmarshall_Enum32(data, pos, table, default)
  stdnse.debug4("MSRPC: Entering unmarshall_Enum32()")
  if(default == nil) then
    default = "<unknown>"
  end
  local pos, val = unmarshall_int32(data, pos)
  for i, v in pairs(table) do
    if(v == val) then
      return pos, i
    end
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_Enum32()")
  return pos, default
end
local function unmarshall_Enum16(data, pos, table, default, pad)
  stdnse.debug4("MSRPC: Entering unmarshall_Enum16()")
  if(default == nil) then
    default = "<unknown>"
  end
  local pos, val = unmarshall_int16(data, pos, pad)
  for i, v in pairs(table) do
    if(v == val) then
      return pos, i
    end
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_Enum16()")
  return pos, default
end
local function marshall_Enum8(val, table, pad)
  local result = 0
  stdnse.debug4("MSRPC: Entering marshall_Enum8()")
  local vals = stringaux.strsplit("|", val)
  local i
  for i = 1, #vals, 1 do
    result = result | table[vals[i]]
  end
  result = marshall_int8(result, pad)
  stdnse.debug4("MSRPC: Leaving marshall_Enum8()")
  return result
end
local function unmarshall_Enum32_array(data, pos, table)
  local array = {}
  local i, v
  local val
  stdnse.debug4("MSRPC: Entering unmarshall_Enum32_array()")
  pos, val = unmarshall_int32(data, pos)
  for i, v in pairs(table) do
    if (v & val) ~= 0 then
      array[#array + 1] = i
    end
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_Enum32_array()")
  return pos, array
end
function unmarshall_raw(data, pos, length)
  local val
  stdnse.debug4("MSRPC: Entering unmarshall_raw()")
  if #data - pos + 1 < length then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_raw(). Please report!")
    return pos, nil
  end
  val, pos = string.unpack(("c%d"):format(length), data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_raw()")
  return pos, val
end
local function marshall_guid(guid)
  local result
  stdnse.debug4("MSRPC: Entering marshall_guid()")
  result = string.pack("<I4I2I2", guid.time_low, guid.time_high, guid.time_hi_and_version) .. guid.clock_seq .. guid.node
  stdnse.debug4("MSRPC: Leaving marshall_guid()")
  return result
end
local function unmarshall_guid(data, pos)
  local fmt = "<I4I2I2c2c6"
  stdnse.debug4("MSRPC: Entering unmarshall_guid()")
  if #data - pos + 1 < string.packsize(fmt) then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_guid(). Please report!")
    return pos, nil
  end
  local guid = {}
  guid.time_low, guid.time_high, guid.time_hi_and_version, guid.clock_seq, guid.node, pos = string.unpack(fmt, data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_guid()")
  return pos, guid
end
function marshall_policy_handle(policy_handle)
  local result
  stdnse.debug4("MSRPC: Entering marshall_policy_handle()")
  result = string.pack("<I4", policy_handle.handle_type) .. marshall_guid(policy_handle.uuid)
  stdnse.debug4("MSRPC: Leaving marshall_policy_handle()")
  return result
end
function unmarshall_policy_handle(data, pos)
  local policy_handle = {}
  stdnse.debug4("MSRPC: Entering unmarshall_policy_handle()")
  pos, policy_handle['handle_type'] = unmarshall_int32(data, pos)
  pos, policy_handle['uuid']        = unmarshall_guid(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_policy_handle()")
  return pos, policy_handle
end
function unmarshall_dom_sid2(data, pos)
  local i
  local sid = {}
  pos, sid['count']          = unmarshall_int32(data, pos)
  pos, sid['sid_rev_num']    = unmarshall_int8(data, pos, false)
  pos, sid['num_auths']      = unmarshall_int8(data, pos, false)
  if #data - pos + 1 < 6 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_dom_sid2(). Please report!")
    return pos, nil
  end
  sid.authority, pos = string.unpack(">I6", data, pos)
  sid['sub_auths']   = {}
  for i = 1, sid['num_auths'], 1 do
    pos, sid['sub_auths'][i] = unmarshall_int32(data, pos)
  end
  local result = string.format("S-%u-%u", sid['sid_rev_num'], sid['authority'])
  for i = 1, sid['num_auths'], 1 do
    result = result .. string.format("-%u", sid['sub_auths'][i])
  end
  return pos, result
end
function unmarshall_dom_sid2_ptr(data, pos)
  return unmarshall_ptr(ALL, data, pos, unmarshall_dom_sid2, {})
end
function marshall_dom_sid2(sid)
  local i
  local pos_next
  local sid_array = {}
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_dom_sid2()")
  if(string.find(sid, "^S%-") == nil) then
    stdnse.debug1("MSRPC: ERROR: Invalid SID encountered: %s\n", sid)
    return nil
  end
  if(string.find(sid, "%-%d+$") == nil) then
    stdnse.debug1("MSRPC: ERROR: Invalid SID encountered: %s\n", sid)
    return nil
  end
  local pos = 3
  pos_next = string.find(sid, "-", pos)
  sid_array.sid_rev_num = tonumber(string.sub(sid, pos, pos_next - 1))
  pos = pos_next + 1
  pos_next = string.find(sid, "-", pos)
  sid_array.authority_high = tonumber(string.sub(sid, pos, pos_next - 1))
  sid_array['sub_auths'] = {}
  i = 1
  repeat
    pos = pos_next + 1
    pos_next = string.find(sid, "-", pos)
    if(pos_next == nil) then
      sid_array['sub_auths'][i] = tonumber(string.sub(sid, pos))
    else
      sid_array['sub_auths'][i] = tonumber(string.sub(sid, pos, pos_next - 1))
    end
    i = i + 1
  until pos_next == nil
  sid_array['num_auths'] = i - 1
  result = {
    string.pack("<I4BB>I6", sid_array.num_auths, sid_array.sid_rev_num, sid_array.num_auths, sid_array.authority),
  }
  for i = 1, sid_array['num_auths'], 1 do
    result[#result+1] = string.pack("<I4", sid_array['sub_auths'][i])
  end
  stdnse.debug4("MSRPC: Leaving marshall_dom_sid2()")
  return table.concat(result)
end
local function marshall_lsa_String_internal(location, str, max_length, do_null)
  local length
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_String_internal()")
  if(max_length == nil) then
    if(str == nil) then
      max_length = 0
    else
      max_length = #str
    end
  end
  if(str == nil) then
    length = 0
  else
    length = #str
  end
  if(do_null == nil) then
    do_null = false
  end
  if(location == HEAD or location == ALL) then
    result = result .. string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(HEAD, marshall_unicode, {str, do_null, max_length}, str)
  end
  if(location == BODY or location == ALL) then
    result = result .. marshall_ptr(BODY, marshall_unicode, {str, do_null, max_length}, str)
  end
  stdnse.debug4("MSRPC: Leaving marshall_lsa_String_internal()")
  return result
end
local function unmarshall_lsa_String_internal(location, data, pos, result)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_String_internal()")
  if(location == HEAD or location == ALL) then
    pos, length = unmarshall_int16(data, pos, false)
    pos, size   = unmarshall_int16(data, pos, false)
    pos, str = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {false})
  end
  if(location == BODY or location == ALL) then
    pos, str = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {false}, result)
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_String_internal()")
  return pos, str
end
function marshall_lsa_String(str, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_String()")
  result = marshall_lsa_String_internal(ALL, str, max_length)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_String()")
  return result
end
function marshall_lsa_String_array(strings)
  local array = {}
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_String_array()")
  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_String_internal
    array[i]['args'] = {strings[i]}
  end
  result = marshall_array(array)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_String_array()")
  return result
end
function marshall_lsa_String_array2(strings)
  local array = {}
  local result
  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_String_internal
    array[i]['args'] = {strings[i], nil, nil, false}
  end
  result = marshall_int32(1000) -- Max length
  .. marshall_int32(0) -- Offset
  .. marshall_array(array)
  return result
end
local lsa_SidType =
{
  SID_NAME_USE_NONE = 0, -- NOTUSED
  SID_NAME_USER     = 1, -- user
  SID_NAME_DOM_GRP  = 2, -- domain group
  SID_NAME_DOMAIN   = 3, -- domain: don't know what this is
  SID_NAME_ALIAS    = 4, -- local group
  SID_NAME_WKN_GRP  = 5, -- well-known group
  SID_NAME_DELETED  = 6, -- deleted account: needed for c2 rating
  SID_NAME_INVALID  = 7, -- invalid account
  SID_NAME_UNKNOWN  = 8, -- oops.
  SID_NAME_COMPUTER = 9  -- machine
}
local lsa_SidType_str =
{
  SID_NAME_USE_NONE = "n/a",
  SID_NAME_USER     = "User",
  SID_NAME_DOM_GRP  = "Domain group",
  SID_NAME_DOMAIN   = "Domain",
  SID_NAME_ALIAS    = "Local group",
  SID_NAME_WKN_GRP  = "Well known group",
  SID_NAME_DELETED  = "Deleted account",
  SID_NAME_INVALID  = "Invalid account",
  SID_NAME_UNKNOWN  = "Unknown account",
  SID_NAME_COMPUTER = "Machine"
}
function marshall_lsa_SidType(sid_type)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_SidType()")
  result = marshall_Enum32(sid_type, lsa_SidType)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_SidType()")
  return result
end
function unmarshall_lsa_SidType(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_SidType()")
  pos, str = unmarshall_Enum16(data, pos, lsa_SidType)
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_SidType()")
  return pos, str
end
function lsa_SidType_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering lsa_SidType_tostr()")
  result = lsa_SidType_str[val]
  stdnse.debug4("MSRPC: Leaving lsa_SidType_tostr()")
  return result
end
local lsa_LookupNamesLevel =
{
  LOOKUP_NAMES_ALL                  = 1,
  LOOKUP_NAMES_DOMAINS_ONLY         = 2,
  LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY  = 3,
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY  = 4,
  LOOKUP_NAMES_FOREST_TRUSTS_ONLY   = 5,
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = 6
}
local lsa_LookupNamesLevel_str =
{
  LOOKUP_NAMES_ALL                  = "All",
  LOOKUP_NAMES_DOMAINS_ONLY         = "Domains only",
  LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY  = "Primary domains only",
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY  = "Uplevel trusted domains only",
  LOOKUP_NAMES_FOREST_TRUSTS_ONLY   = "Forest trusted domains only",
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = "Uplevel trusted domains only (2)"
}
function marshall_lsa_LookupNamesLevel(names_level)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_LookupNamesLevel()")
  result = marshall_Enum32(names_level, lsa_LookupNamesLevel)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_LookupNamesLevel()")
  return result
end
function unmarshall_lsa_LookupNamesLevel(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_LookupNamesLevel()")
  pos, str = unmarshall_Enum32(data, pos, lsa_LookupNamesLevel)
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_LookupNamesLevel()")
  return pos, str
end
function lsa_LookupNamesLevel_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering lsa_LookupNamesLevel_tostr()")
  result = lsa_LookupNamesLevel_str[val]
  stdnse.debug4("MSRPC: Leaving lsa_LookupNamesLevel_tostr()")
  return result
end
local function marshall_lsa_TranslatedSid2(location, sid_type, rid, sid_index, unknown)
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_TranslatedSid2()")
  if(sid_type == nil)  then sid_type  = "SID_NAME_USE_NONE" end
  if(rid == nil)       then rid       = 0 end
  if(sid_index == nil) then sid_index = 0 end
  if(unknown == nil)   then unknown   = 0 end
  if(location == HEAD or location == ALL) then
    result = marshall_lsa_SidType(sid_type)
    .. marshall_int32(rid)
    .. marshall_int32(sid_index)
    .. marshall_int32(unknown)
  end
  if(location == BODY or location == ALL) then
  end
  stdnse.debug4("MSRPC: Leaving marshall_lsa_TranslatedSid2()")
  return result
end
local function unmarshall_lsa_TranslatedSid2(location, data, pos, result)
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['sid_type']  = unmarshall_lsa_SidType(data, pos)
    pos, result['rid']       = unmarshall_int32(data, pos)
    pos, result['sid_index'] = unmarshall_int32(data, pos)
    pos, result['unknown']   = unmarshall_int32(data, pos)
  end
  if(location == BODY or location == ALL) then
  end
  return pos, result
end
local function marshall_lsa_TranslatedName2(location, sid_type, name, sid_index, unknown)
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_TranslatedName2()")
  if(sid_type == nil)  then sid_type  = "SID_NAME_USE_NONE" end
  if(name == nil)      then name      = "" end
  if(sid_index == nil) then sid_index = 0 end
  if(unknown == nil)   then unknown   = 0 end
  if(location == HEAD or location == ALL) then
    result = marshall_lsa_SidType(sid_type)
    .. marshall_lsa_String_internal(HEAD, name)
    .. marshall_int32(sid_index)
    .. marshall_int32(unknown)
  end
  if(location == BODY or location == ALL) then
    result = result .. marshall_lsa_String_internal(BODY, name)
  end
  stdnse.debug4("MSRPC: Leaving marshall_lsa_TranslatedName2()")
  return result
end
local function unmarshall_lsa_TranslatedName2(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TranslatedName2()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['sid_type']  = unmarshall_lsa_SidType(data, pos)
    pos, result['name']      = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['sid_index'] = unmarshall_int32(data, pos)
    pos, result['unknown']   = unmarshall_int32(data, pos)
  end
  if(location == BODY or location == ALL) then
    pos, result['name']      = unmarshall_lsa_String_internal(BODY, data, pos, result['name'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TranslatedName2()")
  return pos, result
end
function marshall_lsa_TransSidArray2(sids)
  local array = {}
  stdnse.debug4("MSRPC: Entering marshall_lsa_TransSidArray2()")
  for i = 1, #sids, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_TranslatedSid2
    array[i]['args'] = {sids[i]['sid_type'], sids[i]['rid'], sids[i]['sid_index'], sids[i]['unknown']}
  end
  local result = marshall_int32(#sids)
  .. marshall_ptr(ALL, marshall_array, {array}, array)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_TransSidArray2()")
  return result
end
local function unmarshall_lsa_StringLarge(location, data, pos, result)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_StringLarge()")
  if(location == HEAD or location == ALL) then
    pos, length = unmarshall_int16(data, pos, false)
    pos, size   = unmarshall_int16(data, pos, false)
    pos, str = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {false})
  end
  if(location == BODY or location == ALL) then
    pos, str = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {false}, result)
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_StringLarge()")
  return pos, str
end
local function unmarshall_lsa_DomainInfo(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_DomainInfo()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['name'] = unmarshall_lsa_StringLarge(HEAD, data, pos)
    pos, result['sid']  = unmarshall_ptr(HEAD, data, pos, unmarshall_dom_sid2)
  end
  if(location == BODY or location == ALL) then
    pos, result['name'] = unmarshall_lsa_StringLarge(BODY, data, pos, result['name'])
    pos, result['sid']  = unmarshall_ptr(BODY, data, pos, unmarshall_dom_sid2, {}, result['sid'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_DomainInfo()")
  return pos, result
end
function unmarshall_lsa_RefDomainList(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_RefDomainList()")
  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['domains'] = unmarshall_ptr(HEAD, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_DomainInfo, {}})
  pos, result['max_size'] = unmarshall_int32(data, pos)
  pos, result['domains'] = unmarshall_ptr(BODY, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_DomainInfo, {}}, result['domains'])
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_RefDomainList()")
  return pos, result
end
function unmarshall_lsa_RefDomainList_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_RefDomainList_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_lsa_RefDomainList, nil)
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_RefDomainList_ptr()")
  return pos, result
end
function unmarshall_lsa_TransSidArray2(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TransSidArray2()")
  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['sid']   = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_TranslatedSid2, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TransSidArray2()")
  return pos, result
end
function marshall_lsa_QosInfo()
  stdnse.debug4("MSRPC: Entering marshall_lsa_QosInfo()")
  local result = marshall_int32(12)
  .. marshall_int16(2, false)
  .. marshall_int8(1, false)
  .. marshall_int8(0, false)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_QosInfo()")
  return result
end
function marshall_lsa_ObjectAttribute()
  stdnse.debug4("MSRPC: Entering marshall_lsa_ObjectAttribute()")
  local result = marshall_int32(24)
  .. marshall_int32(0)  -- Null'ing out these pointers for now. Maybe we'll need them in the future...
  .. marshall_int32(0)
  .. marshall_int32(0)
  .. marshall_int32(0)
  .. marshall_ptr(ALL, marshall_lsa_QosInfo, {})
  stdnse.debug4("MSRPC: Leaving marshall_lsa_ObjectAttribute()")
  return result
end
local function marshall_lsa_SidPtr(location, sid)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_SidPtr()")
  result = marshall_ptr(location, marshall_dom_sid2, {sid}, sid)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_SidPtr()")
  return result
end
function marshall_lsa_SidArray(sids)
  local array = {}
  for i = 1, #sids, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_SidPtr
    array[i]['args'] = {sids[i]}
  end
  local result = marshall_int32(#sids)
  .. marshall_ptr(ALL, marshall_array, {array}, array)
  return result
end
function unmarshall_lsa_SidPtr(location, data, pos, result)
  return unmarshall_ptr(location, data, pos, unmarshall_dom_sid2, {}, result)
end
function unmarshall_lsa_SidArray(data, pos)
  local sidarray = {}
  pos, sidarray['count'] = unmarshall_int32(data, pos)
  pos, sidarray['sids']  = unmarshall_ptr(ALL, data, pos, unmarshall_array, {sidarray['count'], unmarshall_lsa_SidPtr, {}})
  return pos, sidarray
end
function marshall_lsa_TransNameArray2(names)
  local result = ""
  local array = {}
  stdnse.debug4("MSRPC: Entering marshall_lsa_TransNameArray2()")
  if(names == nil) then
    result = result .. marshall_int32(0)
    array = nil
  else
    result = result .. marshall_int32(#names)
    for i = 1, #names, 1 do
      array[i] = {}
      array[i]['func'] = marshall_lsa_TranslatedName2
      array[i]['args'] = {names[i]['sid_type'], names[i]['name'], names[i]['sid_index'], names[i]['unknown']}
    end
  end
  result = result .. marshall_ptr(ALL, marshall_array, {array}, array)
  stdnse.debug4("MSRPC: Leaving marshall_lsa_TransNameArray2()")
  return result
end
function unmarshall_lsa_TransNameArray2(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TransNameArray2()")
  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['names'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_TranslatedName2, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TransNameArray2()")
  return pos, result
end
local winreg_AccessMask =
{
  DELETE_ACCESS          = 0x00010000,
  READ_CONTROL_ACCESS    = 0x00020000,
  WRITE_DAC_ACCESS       = 0x00040000,
  WRITE_OWNER_ACCESS     = 0x00080000,
  SYNCHRONIZE_ACCESS     = 0x00100000,
  ACCESS_SACL_ACCESS     = 0x00800000,
  SYSTEM_SECURITY_ACCESS = 0x01000000,
  MAXIMUM_ALLOWED_ACCESS = 0x02000000,
  GENERIC_ALL_ACCESS     = 0x10000000,
  GENERIC_EXECUTE_ACCESS = 0x20000000,
  GENERIC_WRITE_ACCESS   = 0x40000000,
  GENERIC_READ_ACCESS    = 0x80000000
}
local winreg_AccessMask_str =
{
  DELETE_ACCESS          = "Delete",
  READ_CONTROL_ACCESS    = "Read",
  WRITE_DAC_ACCESS       = "Write",
  WRITE_OWNER_ACCESS     = "Write (owner)",
  SYNCHRONIZE_ACCESS     = "Synchronize",
  ACCESS_SACL_ACCESS     = "Access SACL",
  SYSTEM_SECURITY_ACCESS = "System security",
  MAXIMUM_ALLOWED_ACCESS = "Maximum allowed access",
  GENERIC_ALL_ACCESS     = "All access",
  GENERIC_EXECUTE_ACCESS = "Execute access",
  GENERIC_WRITE_ACCESS   = "Write access",
  GENERIC_READ_ACCESS    = "Read access"
}
function marshall_winreg_AccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_AccessMask()")
  result = marshall_Enum32(accessmask, winreg_AccessMask)
  stdnse.debug4("MSRPC: Leaving marshall_winreg_AccessMask()")
  return result
end
function unmarshall_winreg_AccessMask(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_AccessMask()")
  pos, str = unmarshall_Enum32(data, pos, winreg_AccessMask)
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_AccessMask()")
  return pos, str
end
function winreg_AccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering winreg_AccessMask_tostr()")
  result = winreg_AccessMask_str[val]
  stdnse.debug4("MSRPC: Leaving winreg_AccessMask_tostr()")
  return result
end
winreg_Type =
{
  REG_NONE                       = 0,
  REG_SZ                         = 1,
  REG_EXPAND_SZ                  = 2,
  REG_BINARY                     = 3,
  REG_DWORD                      = 4,
  REG_DWORD_BIG_ENDIAN           = 5,
  REG_LINK                       = 6,
  REG_MULTI_SZ                   = 7,
  REG_RESOURCE_LIST              = 8,
  REG_FULL_RESOURCE_DESCRIPTOR   = 9,
  REG_RESOURCE_REQUIREMENTS_LIST = 10,
  REG_QWORD                      = 11
}
winreg_Type_str =
{
  REG_NONE                       = "None",
  REG_SZ                         = "String",
  REG_EXPAND_SZ                  = "String (expanded)",
  REG_BINARY                     = "Binary",
  REG_DWORD                      = "Dword",
  REG_DWORD_BIG_ENDIAN           = "Dword (big endian)",
  REG_LINK                       = "Link",
  REG_MULTI_SZ                   = "String (multi)",
  REG_RESOURCE_LIST              = "Resource list",
  REG_FULL_RESOURCE_DESCRIPTOR   = "Full resource descriptor",
  REG_RESOURCE_REQUIREMENTS_LIST = "Resource requirements list",
  REG_QWORD                      = "Qword"
}
function marshall_winreg_Type(winregtype)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_Type()")
  result = marshall_Enum32(winregtype, winreg_Type)
  stdnse.debug4("MSRPC: Leaving marshall_winreg_Type()")
  return result
end
function unmarshall_winreg_Type(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_Type()")
  pos, str = unmarshall_Enum32(data, pos, winreg_Type)
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_Type()")
  return pos, str
end
function marshall_winreg_Type_ptr(winreg_type)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_Type_ptr()")
  result = marshall_ptr(ALL, marshall_winreg_Type, {winreg_type}, winreg_type)
  stdnse.debug4("MSRPC: Leaving marshall_winreg_Type_ptr()")
  return result
end
function unmarshall_winreg_Type_ptr(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_Type_ptr()")
  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_winreg_Type, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_Type_ptr()")
  return pos, str
end
function winreg_Type_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering winreg_Type_tostr()")
  result = winreg_Type_str[val]
  stdnse.debug4("MSRPC: Leaving winreg_Type_tostr()")
  return result
end
function marshall_winreg_StringBuf(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_StringBuf()")
  local name = table['name']
  local length
  if(max_length == nil) then
    if(name == nil) then
      max_length = 0
    else
      max_length = #name + 1
    end
  end
  if(name == "") then
    length = 0
    result = string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(ALL, marshall_unicode, {name, false, max_length}, name)
  else
    if(name == nil) then
      length = 0
    else
      length = #name + 1
    end
    result = string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(ALL, marshall_unicode, {name, true, max_length}, name)
  end
  stdnse.debug4("MSRPC: Leaving marshall_winreg_StringBuf()")
  return result
end
function unmarshall_winreg_StringBuf(data, pos)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_StringBuf()")
  pos, length = unmarshall_int16(data, pos, false)
  pos, size   = unmarshall_int16(data, pos, false)
  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_unicode, {true})
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_StringBuf()")
  return pos, str
end
function marshall_winreg_StringBuf_ptr(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_StringBuf_ptr()")
  result = marshall_ptr(ALL, marshall_winreg_StringBuf, {table, max_length}, table)
  stdnse.debug4("MSRPC: Leaving marshall_winreg_StringBuf_ptr()")
  return result
end
function unmarshall_winreg_StringBuf_ptr(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_StringBuf_ptr()")
  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_winreg_StringBuf, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_StringBuf_ptr()")
  return pos, str
end
function marshall_winreg_String(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_String()")
  result = marshall_winreg_StringBuf(table, max_length)
  stdnse.debug4("MSRPC: Leaving marshall_winreg_String()")
  return result
end
function unmarshall_winreg_String(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_String()")
  pos, str = unmarshall_winreg_StringBuf(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_String()")
  return pos, str
end
local srvsvc_ShareType =
{
  STYPE_DISKTREE           = 0x00000000,
  STYPE_DISKTREE_TEMPORARY = 0x40000000,
  STYPE_DISKTREE_HIDDEN    = 0x80000000,
  STYPE_PRINTQ             = 0x00000001,
  STYPE_PRINTQ_TEMPORARY   = 0x40000001,
  STYPE_PRINTQ_HIDDEN      = 0x80000001,
  STYPE_DEVICE             = 0x00000002, -- Serial device
  STYPE_DEVICE_TEMPORARY   = 0x40000002,
  STYPE_DEVICE_HIDDEN      = 0x80000002,
  STYPE_IPC                = 0x00000003, -- Interprocess communication (IPC)
  STYPE_IPC_TEMPORARY      = 0x40000003,
  STYPE_IPC_HIDDEN         = 0x80000003
}
local srvsvc_ShareType_str =
{
  STYPE_DISKTREE           = "Disk",
  STYPE_DISKTREE_TEMPORARY = "Disk (temporary)",
  STYPE_DISKTREE_HIDDEN    = "Disk (hidden)",
  STYPE_PRINTQ             = "Print queue",
  STYPE_PRINTQ_TEMPORARY   = "Print queue (temporary)",
  STYPE_PRINTQ_HIDDEN      = "Print queue (hidden)",
  STYPE_DEVICE             = "Serial device",
  STYPE_DEVICE_TEMPORARY   = "Serial device (temporary)",
  STYPE_DEVICE_HIDDEN      = "Serial device (hidden)",
  STYPE_IPC                = "Interprocess Communication",
  STYPE_IPC_TEMPORARY      = "Interprocess Communication (temporary)",
  STYPE_IPC_HIDDEN         = "Interprocess Communication (hidden)"
}
function marshall_srvsvc_ShareType(sharetype)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_ShareType()")
  result = marshall_Enum32(sharetype, srvsvc_ShareType)
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_ShareType()")
  return result
end
function unmarshall_srvsvc_ShareType(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_ShareType()")
  pos, str = unmarshall_Enum32(data, pos, srvsvc_ShareType)
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_ShareType()")
  return pos, str
end
function srvsvc_ShareType_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering srvsvc_ShareType_tostr()")
  result = srvsvc_ShareType_str[val]
  stdnse.debug4("MSRPC: Leaving srvsvc_ShareType_tostr()")
  return result
end
local function marshall_srvsvc_NetShareInfo0(location, name)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo0()")
  result = marshall_ptr(location, marshall_unicode, {name, true}, name)
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo0()")
  return result
end
local function unmarshall_srvsvc_NetShareInfo0(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo0()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['name'] = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end
  if(location == BODY or location == ALL) then
    pos, result['name'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo0()")
  return pos, result
end
local function marshall_srvsvc_NetShareInfo1(location, name, sharetype, comment)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo1()")
  local name      = marshall_ptr(location, marshall_unicode, {name, true}, name)
  local sharetype = marshall_basetype(location, marshall_srvsvc_ShareType, {sharetype})
  local comment   = marshall_ptr(location, marshall_unicode, {comment, true}, comment)
  result = name .. sharetype .. comment
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo1()")
  return result
end
local function unmarshall_srvsvc_NetShareInfo1(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo1()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['name']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['sharetype'] = unmarshall_srvsvc_ShareType(data, pos)
    pos, result['comment']   = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end
  if(location == BODY or location == ALL) then
    pos, result['name']    = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
    pos, result['comment'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['comment'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo1()")
  return pos, result
end
local function marshall_srvsvc_NetShareInfo2(location, name, sharetype, comment, permissions, max_users, current_users, path, password)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo2()")
  local name          = marshall_ptr(location, marshall_unicode, {name,    true},   name)
  local sharetype     = marshall_basetype(location, marshall_srvsvc_ShareType, {sharetype})
  local comment       = marshall_ptr(location, marshall_unicode, {comment, true},   comment)
  local permissions   = marshall_basetype(location, marshall_int32, {permissions})
  local max_users     = marshall_basetype(location, marshall_int32, {max_users})
  local current_users = marshall_basetype(location, marshall_int32, {current_users})
  local path          = marshall_ptr(location, marshall_unicode, {path, true},      path)
  local password      = marshall_ptr(location, marshall_unicode, {password, true}, password)
  result =  name .. sharetype .. comment .. permissions .. max_users .. current_users .. path .. password
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo2()")
  return result
end
local function unmarshall_srvsvc_NetShareInfo2(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo2()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['name']          = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['sharetype']     = unmarshall_srvsvc_ShareType(data, pos)
    pos, result['comment']       = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['permissions']   = unmarshall_int32(data, pos)
    pos, result['max_users']     = unmarshall_int32(data, pos)
    pos, result['current_users'] = unmarshall_int32(data, pos)
    pos, result['path']          = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['password']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end
  if(location == BODY or location == ALL) then
    pos, result['name']     = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
    pos, result['comment']  = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['comment'])
    pos, result['path']     = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['path'])
    pos, result['password'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['password'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo2()")
  return pos, result
end
function marshall_srvsvc_NetShareCtr0(NetShareCtr0)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr0()")
  if(NetShareCtr0 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr0['array']
    local marshall = nil
    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo0
        marshall[i]['args'] = {array[i]['name']}
      end
    end
    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr0()")
  return table.concat(result)
end
function unmarshall_srvsvc_NetShareCtr0(data, pos)
  local count
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareCtr0()")
  pos, count = unmarshall_int32(data, pos)
  pos, result['array'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {count, unmarshall_srvsvc_NetShareInfo0, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareCtr0()")
  return pos, result
end
function marshall_srvsvc_NetShareCtr1(NetShareCtr1)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr1()")
  if(NetShareCtr1 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr1['array']
    local marshall = nil
    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo1
        marshall[i]['args'] = {array[i]['name'], array[i]['sharetype'], array[i]['comment']}
      end
    end
    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr1()")
  return table.concat(result)
end
function marshall_srvsvc_NetShareCtr2(NetShareCtr2)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr2()")
  if(NetShareCtr2 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr2['array']
    local marshall = nil
    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo2
        marshall[i]['args'] = {array[i]['name'], array[i]['sharetype'], array[i]['comment'], array[i]['permissions'], array[i]['max_users'], array[i]['current_users'], array[i]['path'], array[i]['password']}
        marshall[i]['args'] = {array[i]['name']}
      end
    end
    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr2()")
  return table.concat(result)
end
function marshall_srvsvc_NetShareCtr(level, data)
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr()")
  local marshaller
  if(level == 0) then
    marshaller = marshall_srvsvc_NetShareCtr0
  elseif(level == 1) then
    marshaller = marshall_srvsvc_NetShareCtr1
  elseif(level == 2) then
    marshaller = marshall_srvsvc_NetShareCtr2
  else
    stdnse.debug1("MSRPC: ERROR: Script requested an unknown level for srvsvc_NetShareCtr: %d", level)
    return nil
  end
  local result = string.pack("<I4", level) .. marshall_ptr(ALL, marshaller, {data}, data)
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr()")
  return result
end
function unmarshall_srvsvc_NetShareCtr(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srv_NetShareCtr()")
  pos, level = unmarshall_int32(data, pos)
  if(level == 0) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_NetShareCtr0, {})
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for srvsvc_NetShareCtr: %d", level)
    pos, result = nil, nil
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srv_NetShareCtr()")
  return pos, result
end
function unmarshall_srvsvc_NetShareInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo()")
  pos, level = unmarshall_int32(data, pos)
  if(level == 0) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo0, {}})
  elseif(level == 1) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo1, {}})
  elseif(level == 2) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo2, {}})
  else
    stdnse.debug1("MSRPC: ERROR: Invalid level returned by NetShareInfo: %d\n", level)
    pos, result = nil, nil
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo()")
  return pos, result
end
local function marshall_srvsvc_NetSessInfo10(location, client, user, time, idle_time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo10()")
  local client    = marshall_ptr(location, marshall_unicode, {client, true}, client)
  local user      = marshall_ptr(location, marshall_unicode, {user, true}, user)
  local time      = marshall_basetype(location, marshall_int32, {time})
  local idle_time = marshall_basetype(location, marshall_int32, {idle_time})
  result = client .. user .. time .. idle_time
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo10()")
  return result
end
local function unmarshall_srvsvc_NetSessInfo10(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessInfo10()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['client']    = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['user']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['time']      = unmarshall_int32(data, pos)
    pos, result['idle_time'] = unmarshall_int32(data, pos)
  end
  if(location == BODY or location == ALL) then
    pos, result['client'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['client'])
    pos, result['user']   = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['user'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessInfo10()")
  return pos, result
end
function marshall_srvsvc_NetSessCtr10(NetSessCtr10)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetSessCtr10()")
  if(NetSessCtr10 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetSessCtr10['array']
    local marshall = nil
    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetSessInfo10
        marshall[i]['args'] = {array[i]['client'], array[i]['user'], array[i]['time'], array[i]['idle_time']}
      end
    end
    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetSessCtr10()")
  return table.concat(result)
end
function unmarshall_srvsvc_NetSessCtr10(data, pos)
  local count
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessCtr10()")
  pos, count = unmarshall_int32(data, pos)
  pos, result['array'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {count, unmarshall_srvsvc_NetSessInfo10, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessCtr10()")
  return pos, result
end
function marshall_srvsvc_NetSessCtr(level, data)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr()")
  if(level == 10) then
    result = string.pack("<I4", level) .. marshall_ptr(ALL, marshall_srvsvc_NetSessCtr10, {data}, data)
  else
    stdnse.debug1("MSRPC: ERROR: Script requested an unknown level for srvsvc_NetSessCtr")
    result = nil
  end
  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr()")
  return result
end
function unmarshall_srvsvc_NetSessCtr(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessCtr()")
  level, pos = string.unpack("<I4", data, pos)
  if(level == 10) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_NetSessCtr10, {})
  else
    stdnse.debug1("MSRPC: ERROR: Invalid level returned by NetSessCtr: %d\n", level)
    pos, result = nil, nil
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessCtr()")
  return pos, result
end
function unmarshall_srvsvc_Statistics(data, pos)
  local response = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_Statistics()")
  pos, response['start']          = unmarshall_int32(data, pos)
  pos, response['fopens']         = unmarshall_int32(data, pos)
  pos, response['devopens']       = unmarshall_int32(data, pos)
  pos, response['jobsqueued']     = unmarshall_int32(data, pos)
  pos, response['sopens']         = unmarshall_int32(data, pos)
  pos, response['stimeouts']      = unmarshall_int32(data, pos)
  pos, response['serrorout']      = unmarshall_int32(data, pos)
  pos, response['pwerrors']       = unmarshall_int32(data, pos)
  pos, response['permerrors']     = unmarshall_int32(data, pos)
  pos, response['syserrors']      = unmarshall_int32(data, pos)
  pos, response['bytessent_low']  = unmarshall_int32(data, pos)
  pos, response['bytessent_high'] = unmarshall_int32(data, pos)
  pos, response['bytesrcvd_low']  = unmarshall_int32(data, pos)
  pos, response['bytesrcvd_high'] = unmarshall_int32(data, pos)
  pos, response['avresponse']     = unmarshall_int32(data, pos)
  pos, response['reqbufneed']     = unmarshall_int32(data, pos)
  pos, response['bigbufneed']     = unmarshall_int32(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_Statistics()")
  return pos, response
end
function unmarshall_srvsvc_Statistics_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_Statistics_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_Statistics, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_Statistics_ptr()")
  return pos, result
end
local samr_ConnectAccessMask =
{
  SAMR_ACCESS_CONNECT_TO_SERVER   = 0x00000001,
  SAMR_ACCESS_SHUTDOWN_SERVER     = 0x00000002,
  SAMR_ACCESS_INITIALIZE_SERVER   = 0x00000004,
  SAMR_ACCESS_CREATE_DOMAIN       = 0x00000008,
  SAMR_ACCESS_ENUM_DOMAINS        = 0x00000010,
  SAMR_ACCESS_OPEN_DOMAIN         = 0x00000020
}
local samr_ConnectAccessMask_str =
{
  SAMR_ACCESS_CONNECT_TO_SERVER   = "Connect to server",
  SAMR_ACCESS_SHUTDOWN_SERVER     = "Shutdown server",
  SAMR_ACCESS_INITIALIZE_SERVER   = "Initialize server",
  SAMR_ACCESS_CREATE_DOMAIN       = "Create domain",
  SAMR_ACCESS_ENUM_DOMAINS        = "Enum domains",
  SAMR_ACCESS_OPEN_DOMAIN         = "Open domain"
}
function marshall_samr_ConnectAccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_ConnectAccessMask()")
  result = marshall_Enum32(accessmask, samr_ConnectAccessMask)
  stdnse.debug4("MSRPC: Leaving marshall_samr_ConnectAccessMask()")
  return result
end
function unmarshall_samr_ConnectAccessMask(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_ConnectAccessMask()")
  pos, result = unmarshall_Enum32(data, pos, samr_ConnectAccessMask)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_ConnectAccessMask()")
  return pos, result
end
function samr_ConnectAccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_ConnectAccessMask_tostr()")
  result = samr_ConnectAccessMask_str[val]
  stdnse.debug4("MSRPC: Leaving samr_ConnectAccessMask_tostr()")
  return result
end
local samr_DomainAccessMask =
{
  DOMAIN_ACCESS_LOOKUP_INFO_1  = 0x00000001,
  DOMAIN_ACCESS_SET_INFO_1     = 0x00000002,
  DOMAIN_ACCESS_LOOKUP_INFO_2  = 0x00000004,
  DOMAIN_ACCESS_SET_INFO_2     = 0x00000008,
  DOMAIN_ACCESS_CREATE_USER    = 0x00000010,
  DOMAIN_ACCESS_CREATE_GROUP   = 0x00000020,
  DOMAIN_ACCESS_CREATE_ALIAS   = 0x00000040,
  DOMAIN_ACCESS_LOOKUP_ALIAS   = 0x00000080,
  DOMAIN_ACCESS_ENUM_ACCOUNTS  = 0x00000100,
  DOMAIN_ACCESS_OPEN_ACCOUNT   = 0x00000200,
  DOMAIN_ACCESS_SET_INFO_3     = 0x00000400
}
local samr_DomainAccessMask_str =
{
  DOMAIN_ACCESS_LOOKUP_INFO_1  = "Lookup info (1)",
  DOMAIN_ACCESS_SET_INFO_1     = "Set info (1)",
  DOMAIN_ACCESS_LOOKUP_INFO_2  = "Lookup info (2)",
  DOMAIN_ACCESS_SET_INFO_2     = "Set info (2)",
  DOMAIN_ACCESS_CREATE_USER    = "Create user",
  DOMAIN_ACCESS_CREATE_GROUP   = "Create group",
  DOMAIN_ACCESS_CREATE_ALIAS   = "Create alias",
  DOMAIN_ACCESS_LOOKUP_ALIAS   = "Lookup alias",
  DOMAIN_ACCESS_ENUM_ACCOUNTS  = "Enum accounts",
  DOMAIN_ACCESS_OPEN_ACCOUNT   = "Open account",
  DOMAIN_ACCESS_SET_INFO_3     = "Set info (3)"
}
function marshall_samr_DomainAccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_DomainAccessMask()")
  result = marshall_Enum32(accessmask, samr_DomainAccessMask)
  stdnse.debug4("MSRPC: Leaving marshall_samr_DomainAccessMask()")
  return result
end
function unmarshall_samr_DomainAccessMask(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainAccessMask()")
  pos, result = unmarshall_Enum32(data, pos, samr_DomainAccessMask)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainAccessMask()")
  return pos, result
end
function samr_DomainAccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_DomainAccessMask_tostr()")
  result = samr_DomainAccessMask_str[val]
  stdnse.debug4("MSRPC: Leaving samr_DomainAccessMask_tostr()")
  return result
end
local samr_AcctFlags =
{
  ACB_NONE                    = 0x0000000,
  ACB_DISABLED                = 0x00000001,  -- User account disabled
  ACB_HOMDIRREQ               = 0x00000002,  -- Home directory required
  ACB_PWNOTREQ                = 0x00000004,  -- User password not required
  ACB_TEMPDUP                 = 0x00000008,  -- Temporary duplicate account
  ACB_NORMAL                  = 0x00000010,  -- Normal user account
  ACB_MNS                     = 0x00000020,  -- MNS logon user account
  ACB_DOMTRUST                = 0x00000040,  -- Interdomain trust account
  ACB_WSTRUST                 = 0x00000080,  -- Workstation trust account
  ACB_SVRTRUST                = 0x00000100,  -- Server trust account
  ACB_PWNOEXP                 = 0x00000200,  -- User password does not expire
  ACB_AUTOLOCK                = 0x00000400,  -- Account auto locked
  ACB_ENC_TXT_PWD_ALLOWED     = 0x00000800,  -- Encryped text password is allowed
  ACB_SMARTCARD_REQUIRED      = 0x00001000,  -- Smart Card required
  ACB_TRUSTED_FOR_DELEGATION  = 0x00002000,  -- Trusted for Delegation
  ACB_NOT_DELEGATED           = 0x00004000,  -- Not delegated
  ACB_USE_DES_KEY_ONLY        = 0x00008000,  -- Use DES key only
  ACB_DONT_REQUIRE_PREAUTH    = 0x00010000,  -- Preauth not required
  ACB_PW_EXPIRED              = 0x00020000,  -- Password Expired
  ACB_NO_AUTH_DATA_REQD       = 0x00080000   -- No authorization data required
}
local samr_AcctFlags_str =
{
  ACB_NONE                    = "n/a",
  ACB_DISABLED                = "Account disabled",
  ACB_HOMDIRREQ               = "Home directory required",
  ACB_PWNOTREQ                = "Password not required",
  ACB_TEMPDUP                 = "Temporary duplicate account",
  ACB_NORMAL                  = "Normal user account",
  ACB_MNS                     = "MNS logon user account",
  ACB_DOMTRUST                = "Interdomain trust account",
  ACB_WSTRUST                 = "Workstation trust account",
  ACB_SVRTRUST                = "Server trust account",
  ACB_PWNOEXP                 = "Password does not expire",
  ACB_AUTOLOCK                = "Auto locked",
  ACB_ENC_TXT_PWD_ALLOWED     = "Encryped text password is allowed",
  ACB_SMARTCARD_REQUIRED      = "Smart Card required",
  ACB_TRUSTED_FOR_DELEGATION  = "Trusted for Delegation",
  ACB_NOT_DELEGATED           = "Not delegated",
  ACB_USE_DES_KEY_ONLY        = "Use DES key only",
  ACB_DONT_REQUIRE_PREAUTH    = "Preauth not required",
  ACB_PW_EXPIRED              = "Password Expired",
  ACB_NO_AUTH_DATA_REQD       = "No authorization data required"
}
function marshall_samr_AcctFlags(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_AcctFlags()")
  result = marshall_Enum32(flags, samr_AcctFlags)
  stdnse.debug4("MSRPC: Leaving marshall_samr_AcctFlags()")
  return result
end
function unmarshall_samr_AcctFlags(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_samr_AcctFlags()")
  pos, str = unmarshall_Enum32_array(data, pos, samr_AcctFlags)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_AcctFlags()")
  return pos, str
end
function samr_AcctFlags_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_AcctFlags_tostr()")
  result = samr_AcctFlags_str[val]
  stdnse.debug4("MSRPC: Leaving samr_AcctFlags_tostr()")
  return result
end
local samr_PasswordProperties =
{
  DOMAIN_PASSWORD_COMPLEX         = 0x00000001,
  DOMAIN_PASSWORD_NO_ANON_CHANGE  = 0x00000002,
  DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
  DOMAIN_PASSWORD_LOCKOUT_ADMINS  = 0x00000008,
  DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
  DOMAIN_REFUSE_PASSWORD_CHANGE   = 0x00000020
}
local samr_PasswordProperties_str =
{
  DOMAIN_PASSWORD_COMPLEX         = "Complexity requirements exist",
  DOMAIN_PASSWORD_NO_ANON_CHANGE  = "Must be logged in to change password",
  DOMAIN_PASSWORD_NO_CLEAR_CHANGE = "Cannot change passwords in cleartext",
  DOMAIN_PASSWORD_LOCKOUT_ADMINS  = "Admin account can be locked out",
  DOMAIN_PASSWORD_STORE_CLEARTEXT = "Cleartext passwords can be stored",
  DOMAIN_REFUSE_PASSWORD_CHANGE   = "Passwords cannot be changed"
}
function marshall_samr_PasswordProperties(properties)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_PasswordProperties()")
  result = marshall_Enum32(properties, samr_PasswordProperties)
  stdnse.debug4("MSRPC: Leaving marshall_samr_PasswordProperties()")
  return result
end
function unmarshall_samr_PasswordProperties(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_samr_PasswordProperties()")
  pos, str = unmarshall_Enum32_array(data, pos, samr_PasswordProperties)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_PasswordProperties()")
  return pos, str
end
function samr_PasswordProperties_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_PasswordProperties_tostr()")
  result = samr_PasswordProperties_str[val]
  stdnse.debug4("MSRPC: Leaving samr_PasswordProperties_tostr()")
  return result
end
local function unmarshall_samr_SamEntry(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamEntry()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['idx']       = unmarshall_int32(data, pos)
    pos, result['name']      = unmarshall_lsa_String_internal(HEAD, data, pos)
  end
  if(location == BODY or location == ALL) then
    pos, result['name']      = unmarshall_lsa_String_internal(BODY, data, pos, result['name'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamEntry()")
  return pos, result
end
function unmarshall_samr_SamArray(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamArray()")
  pos, result['count']   = unmarshall_int32(data, pos)
  pos, result['entries'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_samr_SamEntry, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamArray()")
  return pos, result
end
function unmarshall_samr_SamArray_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamArray_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_samr_SamArray, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamArray_ptr()")
  return pos, result
end
local function unmarshall_samr_DispEntryGeneral(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispEntryGeneral()")
  if(result == nil) then
    result = {}
  end
  if(location == HEAD or location == ALL) then
    pos, result['idx']          = unmarshall_int32(data, pos)
    pos, result['rid']          = unmarshall_int32(data, pos)
    pos, result['acct_flags']   = unmarshall_samr_AcctFlags(data, pos)
    pos, result['account_name'] = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['description']  = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['full_name']    = unmarshall_lsa_String_internal(HEAD, data, pos)
  end
  if(location == BODY or location == ALL) then
    pos, result['account_name'] = unmarshall_lsa_String_internal(BODY, data, pos, result['account_name'])
    pos, result['description']  = unmarshall_lsa_String_internal(BODY, data, pos, result['description'])
    pos, result['full_name']    = unmarshall_lsa_String_internal(BODY, data, pos, result['full_name'])
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispEntryGeneral()")
  return pos, result
end
function unmarshall_samr_DispInfoGeneral(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispInfoGeneral()")
  pos, result['count']   = unmarshall_int32(data, pos)
  pos, result['entries'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_samr_DispEntryGeneral, {}})
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispInfoGeneral()")
  return pos, result
end
function unmarshall_samr_DispInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispInfo()")
  pos, level = unmarshall_int16(data, pos)
  if(level == 1) then
    pos, result = unmarshall_samr_DispInfoGeneral(data, pos)
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for samr_DispInfo: %d", level)
    pos, result = nil, nil
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispInfo()")
  return pos, result
end
function unmarshall_samr_DomInfo1(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo1()")
  pos, result['min_password_length']     = unmarshall_int16(data, pos, false)
  pos, result['password_history_length'] = unmarshall_int16(data, pos, false)
  pos, result['password_properties']     = unmarshall_samr_PasswordProperties(data, pos)
  pos, result['max_password_age']        = unmarshall_hyper(data, pos)
  pos, result['min_password_age']        = unmarshall_hyper(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo1()")
  return pos, result
end
function unmarshall_samr_DomInfo8(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo8()")
  pos, result['sequence_num']       = unmarshall_hyper(data, pos)
  pos, result['domain_create_time'] = unmarshall_NTTIME(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo8()")
  return pos, result
end
function unmarshall_samr_DomInfo12(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo12()")
  pos, result['lockout_duration']  = unmarshall_hyper(data, pos)
  pos, result['lockout_window']    = unmarshall_hyper(data, pos)
  pos, result['lockout_threshold'] = unmarshall_int16(data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo12()")
  return pos, result
end
function unmarshall_samr_DomainInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainInfo()")
  pos, level = unmarshall_int16(data, pos)
  if(level == 1) then
    pos, result = unmarshall_samr_DomInfo1(data, pos)
  elseif(level == 8) then
    pos, result = unmarshall_samr_DomInfo8(data, pos)
  elseif(level == 12) then
    pos, result = unmarshall_samr_DomInfo12(data, pos)
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for samr_DomainInfo: %d", level)
    pos, result = nil, nil
  end
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainInfo()")
  return pos, result
end
function unmarshall_samr_DomainInfo_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainInfo_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_samr_DomainInfo, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainInfo_ptr()")
  return pos, result
end
function unmarshall_samr_Ids(data, pos)
  local array
  pos, array = unmarshall_int32_array_ptr(data, pos)
  return pos, array
end
local svcctl_ControlCode =
{
  SERVICE_CONTROL_CONTINUE       = 0x00000003,
  SERVICE_CONTROL_INTERROGATE    = 0x00000004,
  SERVICE_CONTROL_NETBINDADD     = 0x00000007,
  SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A,
  SERVICE_CONTROL_NETBINDENABLE  = 0x00000009,
  SERVICE_CONTROL_NETBINDREMOVE  = 0x00000008,
  SERVICE_CONTROL_PARAMCHANGE    = 0x00000006,
  SERVICE_CONTROL_PAUSE          = 0x00000002,
  SERVICE_CONTROL_STOP           = 0x00000001,
}
local svcctl_ControlCode_str =
{
  SERVICE_CONTROL_CONTINUE       = "Notifies a paused service that it should resume.",
  SERVICE_CONTROL_INTERROGATE    = "Notifies a service that it should report its current status information to the service control manager.",
  SERVICE_CONTROL_NETBINDADD     = "Notifies a network service that there is a new component for binding. Deprecated.",
  SERVICE_CONTROL_NETBINDDISABLE = "Notifies a network service that one of its bindings has been disabled. Deprecated.",
  SERVICE_CONTROL_NETBINDENABLE  = "Notifies a network service that a disabled binding has been enabled. Deprecated",
  SERVICE_CONTROL_NETBINDREMOVE  = "Notifies a network service that a component for binding has been removed. Deprecated",
  SERVICE_CONTROL_PARAMCHANGE    = "Notifies a service that its startup parameters have changed.",
  SERVICE_CONTROL_PAUSE          = "Notifies a service that it should pause.",
  SERVICE_CONTROL_STOP           = "Notifies a service that it should stop."
}
function marshall_svcctl_ControlCode(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_ControlCode()")
  result = marshall_Enum32(flags, svcctl_ControlCode)
  stdnse.debug4("MSRPC: Leaving marshall_svcctl_ControlCode()")
  return result
end
function unmarshall_svcctl_ControlCode(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_ControlCode()")
  pos, str = unmarshall_Enum32_array(data, pos, svcctl_ControlCode)
  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_ControlCode()")
  return pos, str
end
function svcctl_ControlCode_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_ControlCode_tostr()")
  result = svcctl_ControlCode_str[val]
  stdnse.debug4("MSRPC: Leaving svcctl_ControlCode_tostr()")
  return result
end
local svcctl_Type =
{
  SERVICE_TYPE_KERNEL_DRIVER       = 0x01,
  SERVICE_TYPE_FS_DRIVER           = 0x02,
  SERVICE_TYPE_ADAPTER             = 0x04,
  SERVICE_TYPE_RECOGNIZER_DRIVER   = 0x08,
  SERVICE_TYPE_DRIVER              = 0x0B,
  SERVICE_TYPE_WIN32_OWN_PROCESS   = 0x10,
  SERVICE_TYPE_WIN32_SHARE_PROCESS = 0x20,
  SERVICE_TYPE_WIN32               = 0x30
}
function marshall_svcctl_Type(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_Type()")
  result = marshall_Enum32(flags, svcctl_Type)
  stdnse.debug4("MSRPC: Leaving marshall_svcctl_Type()")
  return result
end
function unmarshall_svcctl_Type(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_Type()")
  pos, str = unmarshall_Enum32_array(data, pos, svcctl_Type)
  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_Type()")
  return pos, str
end
--[[Convert a <code>svcctl_Type</code> value to a string that can be shown to the user. This is
function svcctl_Type_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_Type_tostr()")
  result = svcctl_Type_str[val]
  stdnse.debug4("MSRPC: Leaving svcctl_Type_tostr()")
  return result
end]]--
local svcctl_State =
{
  SERVICE_STOPPED          = 0x01,
  SERVICE_START_PENDING    = 0x02,
  SERVICE_STOP_PENDING     = 0x03,
  SERVICE_RUNNING          = 0x04,
  SERVICE_CONTINUE_PENDING = 0x05,
  SERVICE_PAUSE_PENDING    = 0x06,
  SERVICE_PAUSED           = 0x07,
}
function marshall_svcctl_State(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_State()")
  result = marshall_Enum32(flags, svcctl_State)
  stdnse.debug4("MSRPC: Leaving marshall_svcctl_State()")
  return result
end
function unmarshall_svcctl_State(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_State()")
  pos, str = unmarshall_Enum32_array(data, pos, svcctl_State)
  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_State()")
  return pos, str
end
--[[Convert a <code>svcctl_State</code> value to a string that can be shown to the user. This is
function svcctl_State_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_State_tostr()")
  result = svcctl_State_str[val]
  stdnse.debug4("MSRPC: Leaving svcctl_State_tostr()")
  return result
end]]--
function unmarshall_SERVICE_STATUS(data, pos)
  local result = {}
  pos, result['type']              = unmarshall_svcctl_Type(data, pos)
  pos, result['state']             = unmarshall_svcctl_State(data, pos)
  pos, result['controls_accepted'] = unmarshall_svcctl_ControlCode(data, pos)
  pos, result['win32_exit_code']   = unmarshall_int32(data, pos)
  pos, result['service_exit_code'] = unmarshall_int32(data, pos)
  pos, result['check_point']       = unmarshall_int32(data, pos)
  pos, result['wait_hint']         = unmarshall_int32(data, pos)
  return pos, result
end
function unmarshall_lptstr(w_str, startpos)
  local _
  local endpos = startpos
  repeat
    _, endpos = w_str:find("\0\0", endpos, true)
    if not endpos then
      return
    end
  until endpos % 2 == 0
  return endpos + 1, w_str:sub(startpos, endpos)
end
local atsvc_DaysOfMonth =
{
  First           =       0x00000001,
  Second          =       0x00000002,
  Third           =       0x00000004,
  Fourth          =       0x00000008,
  Fifth           =       0x00000010,
  Sixth           =       0x00000020,
  Seventh         =       0x00000040,
  Eighth          =       0x00000080,
  Ninth           =       0x00000100,
  Tenth           =       0x00000200,
  Eleventh        =       0x00000400,
  Twelfth         =       0x00000800,
  Thirteenth      =       0x00001000,
  Fourteenth      =       0x00002000,
  Fifteenth       =       0x00004000,
  Sixteenth       =       0x00008000,
  Seventeenth     =       0x00010000,
  Eighteenth      =       0x00020000,
  Ninteenth       =       0x00040000,
  Twentieth       =       0x00080000,
  Twentyfirst     =       0x00100000,
  Twentysecond    =       0x00200000,
  Twentythird     =       0x00400000,
  Twentyfourth    =       0x00800000,
  Twentyfifth     =       0x01000000,
  Twentysixth     =       0x02000000,
  Twentyseventh   =       0x04000000,
  Twentyeighth    =       0x08000000,
  Twentyninth     =       0x10000000,
  Thirtieth       =       0x20000000,
  Thirtyfirst     =       0x40000000
}
function marshall_atsvc_DaysOfMonth(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_DaysOfMonth()")
  result = marshall_Enum32(flags, atsvc_DaysOfMonth)
  stdnse.debug4("MSRPC: Leaving marshall_atsvc_DaysOfMonth()")
  return result
end
local atsvc_Flags =
{
  JOB_RUN_PERIODICALLY    = 0x01,
  JOB_EXEC_ERROR          = 0x02,
  JOB_RUNS_TODAY          = 0x04,
  JOB_ADD_CURRENT_DATE    = 0x08,
  JOB_NONINTERACTIVE      = 0x10
}
function marshall_atsvc_Flags(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_Flags()")
  result = marshall_Enum8(flags, atsvc_Flags, false)
  stdnse.debug4("MSRPC: Leaving marshall_atsvc_Flags()")
  return result
end
local atsvc_DaysOfWeek =
{
  DAYSOFWEEK_MONDAY    = 0x01,
  DAYSOFWEEK_TUESDAY   = 0x02,
  DAYSOFWEEK_WEDNESDAY = 0x04,
  DAYSOFWEEK_THURSDAY  = 0x08,
  DAYSOFWEEK_FRIDAY    = 0x10,
  DAYSOFWEEK_SATURDAY  = 0x20,
  DAYSOFWEEK_SUNDAY    = 0x40
}
function marshall_atsvc_DaysOfWeek(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_DaysOfWeek()")
  result = marshall_Enum8(flags, atsvc_DaysOfWeek, false)
  stdnse.debug4("MSRPC: Leaving marshall_atsvc_DaysOfWeek()")
  return result
end
function marshall_atsvc_JobInfo(command, time)
  local result = marshall_int32(time)                       -- Job time
  .. marshall_int32(0)                          -- Day of month
  .. marshall_int8(0, false)                    -- Day of week
  .. marshall_atsvc_Flags("JOB_NONINTERACTIVE") -- Flags
  .. marshall_int16(0, false)                   -- Padding
  .. marshall_unicode_ptr(command, true)        -- Command
  return result
end
return _ENV;
