我想编写从python传递的十六进制字符串,因为它在C中的磁盘上。
我的问题是这些值以小端存储,并且值被交换。
示例:
如果我传递一个PyObject,即“abcdef12345123”,它应该在磁盘上写入给定的偏移量,即“abcdef12345123”
以下是此代码的示例代码和结果。
static PyObject *
py_corrupt_disk_object(PyObject *self, PyObject *args)
{
int size, optype, fixcrc;
long offset;
PyObject *baddr;
char *op_value = NULL;
if (!PyArg_ParseTuple(args,"Oliisi", &baddr, &offset, &size, &optype,
&op_value,&fixcrc))
Py_RETURN_NONE;
d_locn_t locn = {};
locn.idx.devid = ((struct py_ifs_baddr*)baddr)->baddr.devid;
locn.idx.drive = ((struct py_ifs_baddr*)baddr)->baddr.drive;
locn.idx.subidx = ((struct py_ifs_baddr*)baddr)->baddr._subblk;
locn.idx.index = ((struct py_ifs_baddr*)baddr)->baddr._block;
d_print("Printing args in py_corrupt_disk_object: \n");
d_print("offset %lu \n",offset);
d_print("fixcrc %d \n",fixcrc);
d_print("size %d \n",size);
d_print("optype %d \n",optype);
d_print("op_value %s \n",op_value);
d_cpr_write(&locn, offset, size, optype, op_value, fixcrc);
Py_RETURN_NONE;
}
PyObject*
d_cpr_write(d_locn_t *locn, int offset, int size, int optype, char *op_value, int fixcrc)
{
cpr_obj* obj = NULL;
struct po_typeinfo *tinfo = NULL;
int obj_size = 0;
d_print("The Values inside d_cpr_write():\n");
d_print("offset %d \n",offset);
d_print("fixcrc %d \n",fixcrc);
d_print("size %d \n",size);
d_print("optype %d \n",optype);
d_print("op_value %s \n",op_value);
if (locn->idx.subidx & BADDR_SIZE_512) {
obj_size = BUFFER_512;
tinfo = find_object('i');
if (locn_iaddr_to_linsnap(locn) != d_OK) {
d_log(d_ERR, "lin snap conversion failed\n");
Py_RETURN_NONE;
}
locn->flags |= DLFLAG_HASXIADDRHINT;
locn->xiaddrhint = d_index_to_baddr(locn->idx);
} else {
obj_size = BUFFER_8192;
tinfo = find_object('b');
}
if (tinfo == NULL) {
d_log(d_ERR, "Only Object i or b supported\n");
Py_RETURN_NONE;
}
obj = alloc_objarg();
// create cpr object
obj->tinfo = tinfo;
obj->locn = *locn;
unsigned char *buff = NULL;
if (!(buff = alloca(obj_size))) {
d_log(d_ERR, "buffer allocation failed\n");
Py_RETURN_NONE;
}
int index, xfered, bit_offset;
if ((xfered = (*obj->tinfo->read)(&obj->locn, buff, obj_size)) < 0) {
d_log(d_ERR, "read failed %d\n", xfered);
Py_RETURN_NONE;
}
if (obj->tinfo->insane != NULL) {
if ((*obj->tinfo->insane)(&obj->locn, buff, obj_size, 0) < 0) {
d_log(d_ERR, "%c object sanity check failed\n",
obj->tinfo->type);
Py_RETURN_NONE;
}
}
d_print("Entering optype\n");
if (optype == 2) { //overwrite
unsigned long opval = strtol(op_value, NULL, 16);
d_print("after rev =%ld ", opval);
memcpy(&buff[offset], &opval, sizeof(opval));
}//End of overwrite
if (fixcrc)
obj->locn.flags |= DLFLAG_WRITE_CRC;
if (!obj->tinfo->write) {
d_log(d_ERR, "no write function supported\n");
Py_RETURN_NONE;
}
if ((xfered = (*obj->tinfo->write)(&obj->locn, buff, obj_size)) < 0) {
d_log(d_ERR, "write failed %d\n", xfered);
Py_RETURN_NONE;
}
Py_RETURN_NONE;
}
./python inject_failures.py --optype=add --fixcrc=1 --object=baddr --baddr=2,3,773463552:512 --offset=16 --mirror=1 --op_value='abcdef12345123' --size=8
> /usr/local_qa/bin/isi_corrupt.py(848)main()
-> if 'add' in options.optype and options.op_value is None:
(Pdb) c
> /usr/local_qa/bin/ inject_failures.py (185)corrupt_diskobject()
-> logging.info("Corrupting disk object %s at %s", obj_type, disk_object)
(Pdb) c
在py_corrupt_disk_object中打印args:
偏移16
fixcrc 1
8号
optype 2
op_value abcdef12345123
d_cpr_write()中的值:
偏移16
fixcrc 1
8号
optype 2
op_value abcdef12345123
输入optype
在rev = 48358647703818531
之后我可以看到数据写得不正确(如果我使用hexdump检查)
在:
<00> 00000010 e0 01 04 00 01 00 00 00 02 00 00 00 00 00 00 00 | ................ |之后:
<00> 00000010 23 51 34 12 ef cd ab 00 02 00 00 00 00 00 00 00 |#Q4 ............. | ==&GT; 23513412 efcdab00有没有办法可以停止这种转换并在C中写入值,从输出看起来就像我们交换字节然后以小端顺序写入磁盘?我正在做一个memcpy()可能有更简单的东西可以帮助我们编写数据而无需交换?
op_value始终为14位或7个字节。如何复制磁盘上的7个字节。 (我是C的新手,所以在提供建议的同时考虑这一点)
答案 0 :(得分:1)
发生的事情很简单:你得到一个字符串,你写了一个长篇:
unsigned long opval = strtol(op_value, NULL, 16);
总之,字节被交换;在字符串中他们不是。所以写一个字符串,每一个都没关系。
<小时/> 所以你想要一个长的,存储的字节反转,哪个是正确的,与非反转的字节一起存储?问题就是原因,因为现在没有任何程序可以再读回来,但唉,这样做的代码是:
if (optype == 2) {
unsigned long opval = strtol(op_value, NULL, 16);
char *longval, *bufp;
longval= (char *)&opval;
bufp= buff;
for (int i=sizeof(long)-1; i>=0; i--)
*bufp++ = *(longval+i);
}