344 lines
8.6 KiB
C
344 lines
8.6 KiB
C
/*
|
|
eas.c
|
|
Copyright (C) 2000 Petr Vandrovec
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
Revision History:
|
|
|
|
1.00 2000, August 26 Petr Vandrovec <vandrove@vc.cvut.cz>
|
|
Initial release.
|
|
|
|
*/
|
|
|
|
#include <ncp/eas.h>
|
|
#include "ncplib_i.h"
|
|
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
|
|
NWCCODE ncp_ea_close(NWCONN_HANDLE conn, uint_fast32_t EAHandle) {
|
|
nuint8 rq[7];
|
|
|
|
BSET (rq, 0, 1);
|
|
WSET_LH(rq, 1, 0);
|
|
DSET_LH(rq, 3, EAHandle);
|
|
|
|
return NWRequestSimple(conn, 0x56, rq, sizeof(rq), NULL);
|
|
}
|
|
|
|
NWCCODE ncp_ea_duplicate(NWCONN_HANDLE conn,
|
|
uint_fast16_t srcFlags,
|
|
uint_fast32_t srcHandleOrVol, uint_fast32_t srcZeroOrDir,
|
|
uint_fast16_t dstFlags,
|
|
uint_fast32_t dstHandleOrVol, uint_fast32_t dstZeroOrDir,
|
|
u_int32_t* duplicateCount,
|
|
u_int32_t* dataSizeDuplicated,
|
|
u_int32_t* keySizeDuplicated) {
|
|
NWCCODE err;
|
|
NW_FRAGMENT rp_frag;
|
|
nuint8 rq[1+4+8+8];
|
|
nuint8 rp[12];
|
|
|
|
BSET (rq, 0, 5);
|
|
WSET_LH(rq, 1, srcFlags);
|
|
WSET_LH(rq, 3, dstFlags);
|
|
DSET_LH(rq, 5, srcHandleOrVol);
|
|
DSET_LH(rq, 9, srcZeroOrDir);
|
|
DSET_LH(rq, 13, dstHandleOrVol);
|
|
DSET_LH(rq, 17, dstZeroOrDir);
|
|
rp_frag.fragSize = sizeof(rp);
|
|
rp_frag.fragAddr.rw = rp;
|
|
|
|
err = NWRequestSimple(conn, 0x56, rq, sizeof(rq), &rp_frag);
|
|
if (err)
|
|
return err;
|
|
if (rp_frag.fragSize < 12)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
if (duplicateCount)
|
|
*duplicateCount = DVAL_LH(rp, 0);
|
|
if (dataSizeDuplicated)
|
|
*dataSizeDuplicated = DVAL_LH(rp, 4);
|
|
if (keySizeDuplicated)
|
|
*keySizeDuplicated = DVAL_LH(rp, 8);
|
|
return 0;
|
|
}
|
|
|
|
NWCCODE ncp_ea_enumerate(NWCONN_HANDLE conn,
|
|
uint_fast16_t flags,
|
|
uint_fast32_t handleOrVol, uint_fast32_t zeroOrDir,
|
|
uint_fast32_t inspectSize,
|
|
const void* key, size_t keyLen,
|
|
struct ncp_ea_enumerate_info* info,
|
|
void* data, size_t datalen, size_t* rdatalen) {
|
|
NWCCODE err;
|
|
void* ptr;
|
|
|
|
if (keyLen && !key)
|
|
return NWE_PARAM_INVALID;
|
|
if (!info)
|
|
return NWE_PARAM_INVALID;
|
|
|
|
ncp_init_request(conn);
|
|
ncp_add_byte(conn, 4);
|
|
ncp_add_word_lh(conn, flags);
|
|
ncp_add_dword_lh(conn, handleOrVol);
|
|
ncp_add_dword_lh(conn, zeroOrDir);
|
|
ncp_add_dword_lh(conn, inspectSize);
|
|
ncp_add_word_lh(conn, info->enumSequence);
|
|
ncp_add_word_lh(conn, keyLen);
|
|
if (keyLen)
|
|
ncp_add_mem(conn, key, keyLen);
|
|
err = ncp_request(conn, 0x56);
|
|
if (!err) {
|
|
if (conn->ncp_reply_size < 24) {
|
|
err = NWE_INVALID_NCP_PACKET_LENGTH;
|
|
} else {
|
|
size_t ln;
|
|
|
|
ptr = ncp_reply_data(conn, 0);
|
|
info->errorCode = DVAL_LH(ptr, 0);
|
|
info->totalEAs = DVAL_LH(ptr, 4);
|
|
info->totalEAsDataSize = DVAL_LH(ptr, 8);
|
|
info->totalEAsKeySize = DVAL_LH(ptr, 12);
|
|
info->newEAhandle = DVAL_LH(ptr, 16);
|
|
info->enumSequence = WVAL_LH(ptr, 20);
|
|
info->returnedItems = WVAL_LH(ptr, 22);
|
|
|
|
ln = conn->ncp_reply_size - 24;
|
|
if (data) {
|
|
if (ln > datalen) {
|
|
ln = datalen;
|
|
err = NWE_BUFFER_OVERFLOW;
|
|
}
|
|
memcpy(data, ncp_reply_data(conn, 24), ln);
|
|
}
|
|
if (rdatalen)
|
|
*rdatalen = ln;
|
|
}
|
|
}
|
|
ncp_unlock_conn(conn);
|
|
return err;
|
|
}
|
|
|
|
NWCCODE ncp_ea_read(NWCONN_HANDLE conn,
|
|
uint_fast16_t flags,
|
|
uint_fast32_t handleOrVol, uint_fast32_t zeroOrDir,
|
|
uint_fast32_t inspectSize,
|
|
const void* key, size_t keyLen,
|
|
uint_fast32_t readOffset,
|
|
struct ncp_ea_read_info* info,
|
|
void* data, size_t datalen, size_t* rdatalen) {
|
|
NWCCODE err;
|
|
void* ptr;
|
|
|
|
if (keyLen && !key)
|
|
return NWE_PARAM_INVALID;
|
|
if (!info)
|
|
return NWE_PARAM_INVALID;
|
|
|
|
ncp_init_request(conn);
|
|
ncp_add_byte(conn, 3);
|
|
ncp_add_word_lh(conn, flags);
|
|
ncp_add_dword_lh(conn, handleOrVol);
|
|
ncp_add_dword_lh(conn, zeroOrDir);
|
|
ncp_add_dword_lh(conn, readOffset);
|
|
ncp_add_dword_lh(conn, inspectSize);
|
|
ncp_add_word_lh(conn, keyLen);
|
|
if (keyLen)
|
|
ncp_add_mem(conn, key, keyLen);
|
|
err = ncp_request(conn, 0x56);
|
|
if (!err) {
|
|
if (conn->ncp_reply_size < 18) {
|
|
err = NWE_INVALID_NCP_PACKET_LENGTH;
|
|
} else {
|
|
size_t ln;
|
|
|
|
ptr = ncp_reply_data(conn, 0);
|
|
info->errorCode = DVAL_LH(ptr, 0);
|
|
info->totalValuesLength = DVAL_LH(ptr, 4);
|
|
info->newEAhandle = DVAL_LH(ptr, 8);
|
|
info->accessFlag = DVAL_LH(ptr, 12);
|
|
ln = WVAL_LH(ptr, 16);
|
|
if (ln + 18 > conn->ncp_reply_size) {
|
|
err = NWE_INVALID_NCP_PACKET_LENGTH;
|
|
} else {
|
|
if (data) {
|
|
if (ln > datalen) {
|
|
ln = datalen;
|
|
err = NWE_BUFFER_OVERFLOW;
|
|
}
|
|
memcpy(data, ncp_reply_data(conn, 18), ln);
|
|
}
|
|
if (rdatalen)
|
|
*rdatalen = ln;
|
|
}
|
|
}
|
|
}
|
|
ncp_unlock_conn(conn);
|
|
return err;
|
|
}
|
|
|
|
NWCCODE ncp_ea_write(NWCONN_HANDLE conn,
|
|
uint_fast16_t flags,
|
|
uint_fast32_t handleOrVol, uint_fast32_t zeroOrDir,
|
|
uint_fast32_t totalWriteSize,
|
|
const void* key, size_t keyLen,
|
|
uint_fast32_t writeOffset,
|
|
uint_fast32_t accessFlag,
|
|
struct ncp_ea_write_info* info,
|
|
const void* data, size_t datalen) {
|
|
NWCCODE err;
|
|
void* ptr;
|
|
|
|
if (keyLen && !key)
|
|
return NWE_PARAM_INVALID;
|
|
if (!info)
|
|
return NWE_PARAM_INVALID;
|
|
|
|
ncp_init_request(conn);
|
|
ncp_add_byte(conn, 2);
|
|
ncp_add_word_lh(conn, flags);
|
|
ncp_add_dword_lh(conn, handleOrVol);
|
|
ncp_add_dword_lh(conn, zeroOrDir);
|
|
ncp_add_dword_lh(conn, totalWriteSize);
|
|
ncp_add_dword_lh(conn, writeOffset);
|
|
ncp_add_dword_lh(conn, accessFlag);
|
|
ncp_add_word_lh(conn, datalen);
|
|
ncp_add_word_lh(conn, keyLen);
|
|
if (keyLen)
|
|
ncp_add_mem(conn, key, keyLen);
|
|
if (datalen)
|
|
ncp_add_mem(conn, data, datalen);
|
|
err = ncp_request(conn, 0x56);
|
|
if (!err) {
|
|
if (conn->ncp_reply_size < 12) {
|
|
err = NWE_INVALID_NCP_PACKET_LENGTH;
|
|
} else {
|
|
ptr = ncp_reply_data(conn, 0);
|
|
info->errorCode = DVAL_LH(ptr, 0);
|
|
info->written = DVAL_LH(ptr, 4);
|
|
info->newEAhandle = DVAL_LH(ptr, 8);
|
|
}
|
|
}
|
|
ncp_unlock_conn(conn);
|
|
return err;
|
|
}
|
|
|
|
NWCCODE ncp_ea_extract_info_level1(const unsigned char* buffer,
|
|
const unsigned char* endbuf,
|
|
struct ncp_ea_info_level1* info, size_t maxsize,
|
|
size_t* needsize, const unsigned char** next) {
|
|
size_t len;
|
|
size_t usedsize;
|
|
const unsigned char* nptr;
|
|
|
|
if (next)
|
|
*next = NULL;
|
|
if (!buffer)
|
|
return NWE_PARAM_INVALID;
|
|
if (buffer + 10 > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
len = WVAL_LH(buffer, 4);
|
|
nptr = buffer + 10 + len;
|
|
if (nptr > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
if (next)
|
|
*next = nptr;
|
|
usedsize = sizeof(*info) - 256 + len + 1;
|
|
if (needsize)
|
|
*needsize = usedsize;
|
|
if (info) {
|
|
if (maxsize < usedsize)
|
|
return NWE_BUFFER_OVERFLOW;
|
|
info->keyLength = len;
|
|
info->valueLength = DVAL_LH(buffer, 0);
|
|
info->accessFlag = DVAL_LH(buffer, 6);
|
|
memcpy(info->key, buffer + 10, len);
|
|
info->key[len] = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
NWCCODE ncp_ea_extract_info_level6(const unsigned char* buffer,
|
|
const unsigned char* endbuf,
|
|
struct ncp_ea_info_level6* info, size_t maxsize,
|
|
size_t* needsize, const unsigned char** next) {
|
|
size_t len;
|
|
size_t usedsize;
|
|
const unsigned char* nptr;
|
|
|
|
if (next)
|
|
*next = NULL;
|
|
if (!buffer)
|
|
return NWE_PARAM_INVALID;
|
|
if (buffer + 18 > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
len = WVAL_LH(buffer, 4);
|
|
nptr = buffer + 18 + len;
|
|
if (nptr > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
if (next)
|
|
*next = nptr;
|
|
usedsize = sizeof(*info) - 256 + len + 1;
|
|
if (needsize)
|
|
*needsize = usedsize;
|
|
if (info) {
|
|
if (maxsize < usedsize)
|
|
return NWE_BUFFER_OVERFLOW;
|
|
info->keyLength = len;
|
|
info->valueLength = DVAL_LH(buffer, 0);
|
|
info->accessFlag = DVAL_LH(buffer, 6);
|
|
info->keyExtants = DVAL_LH(buffer, 10);
|
|
info->valueExtants = DVAL_LH(buffer, 14);
|
|
memcpy(info->key, buffer + 18, len);
|
|
info->key[len] = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
NWCCODE ncp_ea_extract_info_level7(const unsigned char* buffer,
|
|
const unsigned char* endbuf,
|
|
char* key, size_t maxsize, size_t* needsize,
|
|
const unsigned char** next) {
|
|
size_t len;
|
|
size_t usedsize;
|
|
const unsigned char* nptr;
|
|
|
|
if (next)
|
|
*next = NULL;
|
|
if (!buffer)
|
|
return NWE_PARAM_INVALID;
|
|
if (buffer + 2 > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
len = BVAL(buffer, 0);
|
|
nptr = buffer + 2 + len;
|
|
if (nptr > endbuf)
|
|
return NWE_INVALID_NCP_PACKET_LENGTH;
|
|
if (next)
|
|
*next = nptr;
|
|
usedsize = len + 1;
|
|
if (needsize)
|
|
*needsize = usedsize;
|
|
if (key) {
|
|
if (maxsize < usedsize)
|
|
return NWE_BUFFER_OVERFLOW;
|
|
memcpy(key, buffer + 1, len);
|
|
key[len] = 0;
|
|
}
|
|
return 0;
|
|
}
|