LPWORD CreateDlgControl(LPWORD lpw, WORD ctrlclass, WORD id, LPCTSTR caption, DWORD style, short x, short y, short cx, short cy) { LPDLGITEMTEMPLATE lpdit; LPWSTR lpwsz; int nchar, wcharlength; lpw = DWORD_ALIGN(lpw); lpdit = (LPDLGITEMTEMPLATE)lpw; lpdit->style = style; lpdit->dwExtendedStyle = 0; lpdit->x = x ; lpdit->y = y; lpdit->cx = cx; lpdit->cy = cy; lpdit->id = id; // class lpw = (LPWORD)(lpdit + 1); *lpw = 0xFFFF; lpw++; *lpw = ctrlclass; lpw++; // title lpwsz = (LPWSTR)lpw; wcharlength = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, 0); nchar = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, wcharlength); lpw += nchar; // no creation data lpw = NON_DWORD_ALIGN(lpw); *lpw = 0; lpw++; return lpw; }
static size_t ADD_DLGITEM(unsigned char *dlg, short x, short y, short cx, short cy, const char *label, WORD id, WORD type, DWORD style) { unsigned char *p; DLGITEMTEMPLATE dit; p = dlg; dit.style = style; dit.dwExtendedStyle = 0; dit.x = x; dit.y = y; dit.cx = cx; dit.cy = cy; dit.id = id; memcpy(p, &dit, sizeof(dit)); p += sizeof(dit); p += ADD_WORD(p, 0xffff); p += ADD_WORD(p, type); p += ADD_UNICODE_STRING(p, label); /* * creation data? For now, just make this empty, like the resource * compiler does. */ p += ADD_WORD(p, 0x0000); DWORD_ALIGN(p); return (p - dlg); }
static size_t ADD_DLGTEMPLATE(unsigned char *dlg, short x, short y, short cx, short cy, const char *caption, const char *fontname, WORD fontsize, WORD n) { unsigned char *p; DLGTEMPLATE dlt; p = dlg; dlt.style = (DS_MODALFRAME | WS_POPUP); if (caption != NULL) dlt.style |= WS_CAPTION; if (fontname != NULL) dlt.style |= DS_SETFONT; dlt.dwExtendedStyle = 0; dlt.cdit = n; dlt.x = x; dlt.y = y; dlt.cx = cx; dlt.cy = cy; memcpy(p, &dlt, sizeof(dlt)); p += sizeof(dlt); p += ADD_WORD(p, 0x0000); /* menu == none */ p += ADD_WORD(p, 0x0000); /* class == default? */ if (caption != NULL) p += ADD_UNICODE_STRING(p, caption); else p += ADD_WORD(p, 0x0000); if (fontname != NULL) { p += ADD_WORD(p, fontsize); p += ADD_UNICODE_STRING(p, fontname); } DWORD_ALIGN(p); return (p - dlg); }
/* * qnap_log_dump_nstring() * * Display 'n' length bytes of string without hex data. * Usually the string is not null terminated. * * Input: * @ level -- log level. * @ color -- color to be used to display logs. * @ data -- data to log. * @ len -- length of data. * * Output: * None. */ void qnap_log_dump_nstring (int level, char *color, void *data, ssize_t len) { char output[DWORD_ALIGN(SYSLOG_BUFF_LEN + 1)];// tmp buff for null-terminated char *data_ptr = (char *)data; // working pointer /* * Is string null-terminated ? * If yes, no need to process data, just display it. */ if (*(data_ptr + len) == '\0') { QNAP_LOG_RAW(level, color, "%s", data_ptr); return; } /* * Null-terminated our output buffer. */ output[SYSLOG_BUFF_LEN] = '\0'; /* * Display SYSLOG_BUFF_LEN bytes data each time. */ while (len >= SYSLOG_BUFF_LEN) { strncpy(output, data_ptr, SYSLOG_BUFF_LEN); QNAP_LOG_RAW(level, color, "%s", output); len -= SYSLOG_BUFF_LEN; data_ptr += SYSLOG_BUFF_LEN; } /* * Display the rest of data. */ if (len > 0) { strncpy(output, data_ptr, len); output[len] = '\0'; QNAP_LOG_RAW(level, color, "%s", output); } }
LPWORD NON_DWORD_ALIGN(LPWORD lpIn) { return (DWORD_ALIGN(lpIn - 1) + 1); }
/*===========================================================================* * do_getdents * *===========================================================================*/ int do_getdents() { /* Retrieve directory entries. */ char name[NAME_MAX+1]; struct inode *ino, *child; struct dirent *dent; struct sffs_attr attr; size_t len, off, user_off, user_left; off_t pos; int r; /* must be at least sizeof(struct dirent) + NAME_MAX */ static char buf[BLOCK_SIZE]; attr.a_mask = SFFS_ATTR_MODE; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) return EINVAL; if (m_in.REQ_SEEK_POS_HI != 0) return EINVAL; if (!IS_DIR(ino)) return ENOTDIR; /* We are going to need at least one free inode to store children in. */ if (!have_free_inode()) return ENFILE; /* If we don't have a directory handle yet, get one now. */ if ((r = get_handle(ino)) != OK) return r; off = 0; user_off = 0; user_left = m_in.REQ_MEM_SIZE; /* We use the seek position as file index number. The first position is for * the "." entry, the second position is for the ".." entry, and the next * position numbers each represent a file in the directory. */ for (pos = m_in.REQ_SEEK_POS_LO; ; pos++) { /* Determine which inode and name to use for this entry. * We have no idea whether the host will give us "." and/or "..", * so generate our own and skip those from the host. */ if (pos == 0) { /* Entry for ".". */ child = ino; strcpy(name, "."); get_inode(child); } else if (pos == 1) { /* Entry for "..", but only when there is a parent. */ if (ino->i_parent == NULL) continue; child = ino->i_parent; strcpy(name, ".."); get_inode(child); } else { /* Any other entry, not being "." or "..". */ r = sffs_table->t_readdir(ino->i_dir, pos - 2, name, sizeof(name), &attr); if (r != OK) { /* No more entries? Then close the handle and stop. */ if (r == ENOENT) { put_handle(ino); break; } /* FIXME: what if the error is ENAMETOOLONG? */ return r; } if (!strcmp(name, ".") || !strcmp(name, "..")) continue; if ((child = lookup_dentry(ino, name)) == NULL) { child = get_free_inode(); /* We were promised a free inode! */ assert(child != NULL); child->i_flags = MODE_TO_DIRFLAG(attr.a_mode); add_dentry(ino, name, child); } } len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name)); /* Is the user buffer too small to store another record? * Note that we will be rerequesting the same dentry upon a subsequent * getdents call this way, but we really need the name length for this. */ if (user_off + off + len > user_left) { put_inode(child); /* Is the user buffer too small for even a single record? */ if (user_off == 0 && off == 0) return EINVAL; break; } /* If our own buffer cannot contain the new record, copy out first. */ if (off + len > sizeof(buf)) { r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT, user_off, (vir_bytes) buf, off, D); if (r != OK) { put_inode(child); return r; } user_off += off; user_left -= off; off = 0; } /* Fill in the actual directory entry. */ dent = (struct dirent *) &buf[off]; dent->d_ino = INODE_NR(child); dent->d_off = pos; dent->d_reclen = len; strcpy(dent->d_name, name); off += len; put_inode(child); } /* If there is anything left in our own buffer, copy that out now. */ if (off > 0) { r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT, user_off, (vir_bytes) buf, off, D); if (r != OK) return r; user_off += off; } m_out.RES_SEEK_POS_HI = 0; m_out.RES_SEEK_POS_LO = pos; m_out.RES_NBYTES = user_off; return OK; }
/*===========================================================================* * fs_getdents * *===========================================================================*/ int fs_getdents(void) { /* Retrieve directory entries. */ struct inode *node, *child = NULL; struct dirent *dent; char *name; size_t len, off, user_off, user_left; off_t pos; int r, skip, get_next, indexed; static char buf[GETDENTS_BUFSIZ]; if (fs_m_in.REQ_SEEK_POS_HI != 0) return EIO; if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL) return EINVAL; off = 0; user_off = 0; user_left = fs_m_in.REQ_MEM_SIZE; indexed = node->i_indexed; get_next = FALSE; child = NULL; /* Call the getdents hook, if any, to "refresh" the directory. */ if (!is_inode_deleted(node) && vtreefs_hooks->getdents_hook != NULL) { r = vtreefs_hooks->getdents_hook(node, get_inode_cbdata(node)); if (r != OK) return r; } for (pos = fs_m_in.REQ_SEEK_POS_LO; ; pos++) { /* Determine which inode and name to use for this entry. */ if (pos == 0) { /* The "." entry. */ child = node; name = "."; } else if (pos == 1) { /* The ".." entry. */ child = get_parent_inode(node); if (child == NULL) child = node; name = ".."; } else if (pos - 2 < indexed) { /* All indexed entries. */ child = get_inode_by_index(node, pos - 2); /* If there is no inode with this particular index, * continue with the next index number. */ if (child == NULL) continue; name = child->i_name; } else { /* All non-indexed entries. */ /* If this is the first loop iteration, first get to * the non-indexed child identified by the current * position. */ if (get_next == FALSE) { skip = pos - indexed - 2; child = get_first_inode(node); /* Skip indexed children. */ while (child != NULL && child->i_index != NO_INDEX) child = get_next_inode(child); /* Skip to the right position. */ while (child != NULL && skip-- > 0) child = get_next_inode(child); get_next = TRUE; } else { child = get_next_inode(child); } /* No more children? Then stop. */ if (child == NULL) break; assert(!is_inode_deleted(child)); name = child->i_name; } len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name)); /* Is the user buffer too small to store another record? */ if (user_off + off + len > user_left) { /* Is the user buffer too small for even a single * record? */ if (user_off == 0 && off == 0) return EINVAL; break; } /* If our own buffer cannot contain the new record, copy out * first. */ if (off + len > sizeof(buf)) { r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, user_off, (vir_bytes) buf, off, D); if (r != OK) return r; user_off += off; user_left -= off; off = 0; } /* Fill in the actual directory entry. */ dent = (struct dirent *) &buf[off]; dent->d_ino = get_inode_number(child); dent->d_off = pos; dent->d_reclen = len; strcpy(dent->d_name, name); off += len; } /* If there is anything left in our own buffer, copy that out now. */ if (off > 0) { r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, user_off, (vir_bytes) buf, off, D); if (r != OK) return r; user_off += off; } fs_m_out.RES_SEEK_POS_HI = 0; fs_m_out.RES_SEEK_POS_LO = pos; fs_m_out.RES_NBYTES = user_off; return OK; }
/* * qnap_log_dump_data() * * Log data in hex format followed by ASCII character. * i.e in the format * XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX ...... CCCCCCCC CCCCCCCC * * Input: * @ level -- log level. * @ color -- color to be used to display logs. * @ data -- data to log. * @ len -- length of data. * Output: * None. */ void qnap_log_dump_data (int level, char *color, void *data, ssize_t len) { uint8_t *ud = (uint8_t *)data; // cast to unsigned char output[DWORD_ALIGN(SYSLOG_BUFF_LEN)], *out;// tmp log buffer ssize_t i; while (len > 0) { /* * Output data line-by-line, format to tmp buffer first. */ memset(output, ' ', sizeof(output)); // set to all spaces first out = &output[2]; // first 2 chars are spaces /* * Display the first 16 bytes in hex. */ for (i = 0; (i < len) && (i < 16); i++) { out += sprintf(out, "%02X ", ud[i]); if (i == 7) { /* * Note: sprintf() will null terminated the string, need to reset * back to space character */ *out++ = ' '; } } *out = ' '; // Same reason as above /* * Jump to position 51 because the last line of data might not be * 16 bytes. */ out = &output[51]; for (i = 0; i < 3; i++) { *out++ = ' '; // output 3 spaces } out++; // one space /* * Now for ASCII characters display. */ for (i = 0; (i < len) && (i < 16); i++) { *out++ = isprint(ud[i]) ? ud[i] : '.'; if (i == 7) { out++; } } *out++ = '\0'; /* * Display the line. */ QNAP_LOG_RAW(level, color, "%s\n", output); /* * Advance to next line. */ ud += 16; len -= 16; } }