⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cramfs_cb.c

📁 在win(2000/2003)下面制作CRAMFS映像文件 专门用于嵌入式Linux开发 由于网络上没有类似的软件 索性自己写了一个 经过测试OK 全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef CRAMFS_CB_C
#define CRAMFS_CB_C
//---------------------------------------------------------
/* Exit codes used by mkfs-type programs */
#define MKFS_OK          0      /* No errors */
#define MKFS_ERROR       8      /* Operational error */
#define MKFS_USAGE       16     /* Usage or syntax error */

/* The kernel only supports PAD_SIZE of 0 and 512. */
#define PAD_SIZE 512

/* The kernel assumes PAGE_CACHE_SIZE as block size. */
#define PAGE_CACHE_SIZE (4096)

/*
 * The longest filename component to allow for in the input directory tree.
 * ext2fs (and many others) allow up to 255 bytes.  A couple of filesystems
 * allow longer (e.g. smbfs 1024), but there isn't much use in supporting
 * >255-byte names in the input directory tree given that such names get
 * truncated to CRAMFS_MAXPATHLEN (252 bytes) when written to cramfs.
 *
 * Old versions of mkcramfs generated corrupted filesystems if any input
 * filenames exceeded CRAMFS_MAXPATHLEN (252 bytes), however old
 * versions of cramfsck seem to have been able to detect the corruption.
 */
#define MAX_INPUT_NAMELEN 255

/*
 * Maximum size fs you can create is roughly 256MB.  (The last file's
 * data must begin within 256MB boundary but can extend beyond that.)
 *
 * Note that if you want it to fit in a ROM then you're limited to what the
 * hardware and kernel can support.
 */
#define MAXFSLEN ((((1 << CRAMFS_OFFSET_WIDTH) - 1) << 2) /* offset */ \
                  + (1 << CRAMFS_SIZE_WIDTH) - 1 /* filesize */ \
                  + (1 << CRAMFS_SIZE_WIDTH) * 4 / PAGE_CACHE_SIZE /* block pointers */ )

static const char *progname = "mkcramfs";
static unsigned int blksize = PAGE_CACHE_SIZE;
static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */
static int image_length = 0;

/*
 * If opt_holes is set, then mkcramfs can create explicit holes in the
 * data, which saves 26 bytes per hole (which is a lot smaller a
 * saving than most most filesystems).
 *
 * Note that kernels up to at least 2.3.39 don't support cramfs holes,
 * which is why this is turned off by default.
 *
 * If opt_verbose is 1, be verbose.  If it is higher, be even more verbose.
 */
static u32 opt_edition = 0;
static int opt_errors = 0;
static int opt_holes = 0;
static int opt_pad = 0;
static int opt_verbose = 0;
static char *opt_image = NULL;
static char *opt_name = NULL;

static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
//---------------------------------------------------------
/* In-core version of inode / directory entry. */
struct entry {
        /* stats */
        unsigned char *name;
        unsigned int mode, size, uid, gid;

        /* these are only used for non-empty files */
        char *path;             /* always null except non-empty files */
        int fd;                 /* temporarily open files while mmapped */

        HANDLE fh;      /*append by mordecay, for file mmap in winNT*/
        HANDLE fm;      /*append by mordecay, for file mmap in winNT*/

        /* FS data */
        void *uncompressed;
        /* points to other identical file */
        struct entry *same;
        unsigned int offset;            /* pointer to compressed data in archive */
        unsigned int dir_offset;        /* Where in the archive is the directory entry? */

        /* organization */
        struct entry *child; /* null for non-directories and empty directories */
        struct entry *next;
};
//---------------------------------------------------------
/* Input status of 0 to print help and exit without an error. */
static void usage(int status)
{
        /*
        FILE *stream = status ? stderr : stdout;

        fprintf(stream, "usage: %s [-h] [-e edition] [-i file] [-n name] dirname outfile\n"
                " -h         print this help\n"
                " -E         make all warnings errors (non-zero exit status)\n"
                " -e edition set edition number (part of fsid)\n"
                " -i file    insert a file image into the filesystem (requires >= 2.4.0)\n"
                " -n name    set name of cramfs filesystem\n"
                " -p         pad by %d bytes for boot code\n"
                " -s         sort directory entries (old option, ignored)\n"
                " -v         be more verbose\n"
                " -z         make explicit holes (requires >= 2.3.39)\n"
                " dirname    root of the directory tree to be compressed\n"
                " outfile    output file\n", progname, PAD_SIZE);

        */

        exit(status);
}
//---------------------------------------------------------
static void die(int status, int syserr, const char *fmt, ...)
{
        va_list arg_ptr;
        char stext[512];

        va_start(arg_ptr, fmt);
        vsprintf(stext, fmt, arg_ptr);
        va_end(arg_ptr);

        ShowMessage(stext);

        exit(status);
}
//---------------------------------------------------------
static void map_entry(struct entry *entry)
{
        /*
        if (entry->path) {
                entry->fd = open(entry->path, O_RDONLY);
                if (entry->fd < 0) {
                        die(MKFS_ERROR, 1, "open failed: %s", entry->path);
                }
                entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, entry->fd, 0);
                if (entry->uncompressed == MAP_FAILED) {
                        die(MKFS_ERROR, 1, "mmap failed: %s", entry->path);
                }
        }
        */

        if(entry->path)
        {
                DWORD f_size;

                DWORD Access = GENERIC_READ;
                DWORD AShare = FILE_SHARE_READ;
                DWORD Create = OPEN_EXISTING;
                DWORD Attrib = FILE_FLAG_SEQUENTIAL_SCAN;

                entry->fh = CreateFile(
                        entry->path, Access, AShare, 0, Create, Attrib, 0);

                if(entry->fh == INVALID_HANDLE_VALUE)
                {
                        die(MKFS_ERROR, 1, "open failed: %s", entry->path);
                }

                f_size = SetFilePointer(entry->fh, 0, 0, FILE_END);

                         SetFilePointer(entry->fh, 0, 0, FILE_BEGIN);

                entry->fd = (int)entry->fh;

                entry->fm = CreateFileMapping(
                        entry->fh, NULL, PAGE_READONLY, 0, f_size, NULL);

                if(entry->fm == INVALID_HANDLE_VALUE)
                {
                        die(MKFS_ERROR, 1, "fmap failed: %s", entry->path);
                }

                entry->uncompressed = MapViewOfFile(
                        entry->fm, FILE_MAP_READ, 0, 0, f_size);

                if(entry->uncompressed == NULL)
                {
                        die(MKFS_ERROR, 1, "mapv failed: %s", entry->path);
                }
        }
}
//---------------------------------------------------------
static void unmap_entry(struct entry *entry)
{
        /*
        if (entry->path) {
                if (munmap(entry->uncompressed, entry->size) < 0) {
                        die(MKFS_ERROR, 1, "munmap failed: %s", entry->path);
                }
                close(entry->fd);
        }
        */

        if(entry->path)
        {
                UnmapViewOfFile(entry->uncompressed);

                CloseHandle(entry->fm);
                CloseHandle(entry->fh);

                entry->fm = INVALID_HANDLE_VALUE;
                entry->fh = INVALID_HANDLE_VALUE;
        }
}
//---------------------------------------------------------
static int find_identical_file(struct entry *orig, struct entry *newfile)
{
        if (orig == newfile)
                return 1;
        if (!orig)
                return 0;
        if (orig->size == newfile->size && (orig->path || orig->uncompressed))
        {
                map_entry(orig);
                map_entry(newfile);
                if (!memcmp(orig->uncompressed, newfile->uncompressed, orig->size))
                {
                        newfile->same = orig;
                        unmap_entry(newfile);
                        unmap_entry(orig);
                        return 1;
                }
                unmap_entry(newfile);
                unmap_entry(orig);
        }
        return (find_identical_file(orig->child, newfile) ||
                find_identical_file(orig->next, newfile));
}
//---------------------------------------------------------
static void eliminate_doubles(struct entry *root, struct entry *orig) {
        if (orig) {
                if (orig->size && (orig->path || orig->uncompressed))
                        find_identical_file(root, orig);
                eliminate_doubles(root, orig->child);
                eliminate_doubles(root, orig->next);
        }
}
//---------------------------------------------------------
/*
 * We define our own sorting function instead of using alphasort which
 * uses strcoll and changes ordering based on locale information.
 */
struct dirent
{
        int d_ino;
        int d_off;

        short           d_reclen;
        unsigned char   d_type;
        char            d_name[256];

} g_dirent_array[65536];

static int cramsort(const void *a, const void *b)
{
        return strcmp ((*(const struct dirent **) a)->d_name,
                       (*(const struct dirent **) b)->d_name);
}

static int scandir(const char *path,
        struct dirent ***name_list,
        int (*select)(const void *),
        int (*compar)(const void *, const void *))
{
        int i = 1;

        TSearchRec search_rec;
        AnsiString search_str;

        search_str.sprintf("%s\\*.*",path);

        if(FindFirst(search_str, faAnyFile, search_rec) == 0)
        {
                (*name_list) = (struct dirent **)
                        malloc(sizeof(long[65536]));

                (*name_list)[0] = g_dirent_array;

                StrPLCopy(g_dirent_array->d_name,
                        search_rec.Name, 255);

                while(0 == FindNext(search_rec))
                {
                    (*name_list)[i] = g_dirent_array + i;

                    StrPLCopy(g_dirent_array[i].d_name,
                            search_rec.Name, 255);

                    if((i ++) >= 65535)
                        break;
                };

                FindClose(search_rec);

                qsort((*name_list), i, sizeof(long), compar);

                return(i);
        }

        return(-1);
}
//---------------------------------------------------------
struct stat
{
        DWORD st_dev;
        DWORD st_ino;

        DWORD st_mode;
        DWORD st_nlink;

        DWORD st_uid;
        DWORD st_gid;

        DWORD st_rdev;
        DWORD st_size;

        DWORD st_blksize;
        DWORD st_blocks;

        DWORD  st_atime;
        DWORD  st_mtime;
        DWORD  st_ctime;
};
//---------------------------------------------------------
#define S_IFMT  0170000
#define S_IFDIR 0040000
#define S_IFREG 0100000

#define S_ISDIR(x) (((x) & S_IFDIR) == S_IFDIR)
#define S_ISREG(x) (((x) & S_IFREG) == S_IFREG)
//---------------------------------------------------------
static int lstat(const char *file_name, struct stat *buf)
{
        memset(buf, 0, sizeof(stat));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -