Преглед изворни кода

[efi] Add EFI string formatting functions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown пре 13 година
родитељ
комит
870524a3b2

+ 23
- 0
src/include/ipxe/efi/efi_strings.h Прегледај датотеку

@@ -0,0 +1,23 @@
1
+#ifndef _IPXE_EFI_STRINGS_H
2
+#define _IPXE_EFI_STRINGS_H
3
+
4
+/** @file
5
+ *
6
+ * EFI strings
7
+ */
8
+
9
+FILE_LICENCE ( GPL2_OR_LATER );
10
+
11
+#include <stddef.h>
12
+#include <stdint.h>
13
+#include <stdarg.h>
14
+
15
+extern int efi_vsnprintf ( wchar_t *wbuf, size_t wsize, const char *fmt,
16
+			   va_list args );
17
+extern int efi_snprintf ( wchar_t *wbuf, size_t wsize, const char *fmt, ... );
18
+extern int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
19
+			    va_list args );
20
+extern int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize,
21
+			   const char *fmt, ... );
22
+
23
+#endif /* _IPXE_EFI_STRINGS_H */

+ 5
- 8
src/interface/efi/efi_driver.c Прегледај датотеку

@@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
23 23
 #include <ipxe/efi/efi.h>
24 24
 #include <ipxe/efi/Protocol/DriverBinding.h>
25 25
 #include <ipxe/efi/Protocol/ComponentName2.h>
26
+#include <ipxe/efi/efi_strings.h>
26 27
 #include <ipxe/efi/efi_driver.h>
27 28
 #include <config/general.h>
28 29
 
@@ -107,8 +108,6 @@ EFI_STATUS efi_driver_install ( struct efi_driver *efidrv ) {
107 108
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
108 109
 	EFI_DRIVER_BINDING_PROTOCOL *driver = &efidrv->driver;
109 110
 	EFI_COMPONENT_NAME2_PROTOCOL *wtf = &efidrv->wtf;
110
-	char buf[ sizeof ( efidrv->wname ) / sizeof ( efidrv->wname[0] ) ];
111
-	unsigned int i;
112 111
 	EFI_STATUS efirc;
113 112
 
114 113
 	/* Configure driver binding protocol */
@@ -120,12 +119,10 @@ EFI_STATUS efi_driver_install ( struct efi_driver *efidrv ) {
120 119
 	wtf->SupportedLanguages = "en";
121 120
 
122 121
 	/* Fill in driver name */
123
-	snprintf ( buf, sizeof ( buf ), PRODUCT_SHORT_NAME " - %s",
124
-		   efidrv->name );
125
-	for ( i = 0 ; i < sizeof ( buf ) ; i++ ) {
126
-		/* Damn Unicode names */
127
-		efidrv->wname[i] = *( ( ( unsigned char * ) buf ) + i );
128
-	}
122
+	efi_snprintf ( efidrv->wname,
123
+		       ( sizeof ( efidrv->wname ) /
124
+			 sizeof ( efidrv->wname[0] ) ),
125
+		       PRODUCT_SHORT_NAME " - %s", efidrv->name );
129 126
 
130 127
 	/* Install driver */
131 128
 	if ( ( efirc = bs->InstallMultipleProtocolInterfaces (

+ 4
- 7
src/interface/efi/efi_snp.c Прегледај датотеку

@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
30 30
 #include <ipxe/efi/efi.h>
31 31
 #include <ipxe/efi/efi_pci.h>
32 32
 #include <ipxe/efi/efi_driver.h>
33
+#include <ipxe/efi/efi_strings.h>
33 34
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
34 35
 #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
35 36
 #include <ipxe/efi/Protocol/DevicePath.h>
@@ -772,7 +773,6 @@ static int efi_snp_probe ( struct net_device *netdev ) {
772 773
 	EFI_DEVICE_PATH_PROTOCOL *path_end;
773 774
 	MAC_ADDR_DEVICE_PATH *macpath;
774 775
 	size_t path_prefix_len = 0;
775
-	unsigned int i;
776 776
 	EFI_STATUS efirc;
777 777
 	int rc;
778 778
 
@@ -831,12 +831,9 @@ static int efi_snp_probe ( struct net_device *netdev ) {
831 831
 		  sizeof ( snpdev->nii.StringId ) );
832 832
 
833 833
 	/* Populate the device name */
834
-	for ( i = 0 ; i < sizeof ( netdev->name ) ; i++ ) {
835
-		/* Damn Unicode names */
836
-		assert ( i < ( sizeof ( snpdev->name ) /
837
-			       sizeof ( snpdev->name[0] ) ) );
838
-		snpdev->name[i] = netdev->name[i];
839
-	}
834
+	efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
835
+				       sizeof ( snpdev->name[0] ) ),
836
+		       "%s", netdev->name );
840 837
 
841 838
 	/* Populate the device path */
842 839
 	memcpy ( &snpdev->path, efipci->path, path_prefix_len );

+ 147
- 0
src/interface/efi/efi_strings.c Прегледај датотеку

@@ -0,0 +1,147 @@
1
+/*
2
+ * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stddef.h>
22
+#include <stdarg.h>
23
+#include <ipxe/vsprintf.h>
24
+#include <ipxe/efi/efi_strings.h>
25
+
26
+/** Context used by efi_vsnprintf() and friends */
27
+struct efi_sputc_context {
28
+	/** printf context */
29
+	struct printf_context ctx;
30
+	/** Buffer for formatted string (used by efi_printf_sputc()) */
31
+	wchar_t *buf;
32
+	/** Buffer length (used by efi_printf_sputc())
33
+	 *
34
+	 * Note that this is a number of wide characters, not a number
35
+	 * of bytes.
36
+	 */
37
+	size_t max_wlen;
38
+};
39
+
40
+/**
41
+ * Write wide character to buffer
42
+ *
43
+ * @v ctx		Context
44
+ * @v c			Character
45
+ */
46
+static void efi_printf_sputc ( struct printf_context *ctx, unsigned int c ) {
47
+	struct efi_sputc_context * sctx =
48
+		container_of ( ctx, struct efi_sputc_context, ctx );
49
+
50
+	if ( ctx->len < sctx->max_wlen )
51
+		sctx->buf[ctx->len] = c;
52
+}
53
+
54
+/**
55
+ * Write a formatted string to a wide-character buffer
56
+ *
57
+ * @v wbuf		Buffer into which to write the string
58
+ * @v wsize		Size of buffer (in wide characters)
59
+ * @v fmt		Format string
60
+ * @v args		Arguments corresponding to the format string
61
+ * @ret wlen		Length of formatted string (in wide characters)
62
+ *
63
+ * If the buffer is too small to contain the string, the returned
64
+ * length is the length that would have been written had enough space
65
+ * been available.
66
+ */
67
+int efi_vsnprintf ( wchar_t *wbuf, size_t wsize, const char *fmt,
68
+		    va_list args ) {
69
+	struct efi_sputc_context sctx;
70
+	size_t wlen;
71
+	size_t wend;
72
+
73
+	/* Hand off to vcprintf */
74
+	sctx.ctx.handler = efi_printf_sputc;
75
+	sctx.buf = wbuf;
76
+	sctx.max_wlen = wsize;
77
+	wlen = vcprintf ( &sctx.ctx, fmt, args );
78
+
79
+	/* Add trailing NUL */
80
+	if ( wsize ) {
81
+		wend = wsize - 1;
82
+		if ( wlen < wend )
83
+			wend = wlen;
84
+		wbuf[wend] = '\0';
85
+	}
86
+
87
+	return wlen;
88
+}
89
+
90
+/**
91
+ * Write a formatted string to a buffer
92
+ *
93
+ * @v wbuf		Buffer into which to write the string
94
+ * @v wsize		Size of buffer (in wide characters)
95
+ * @v fmt		Format string
96
+ * @v ...		Arguments corresponding to the format string
97
+ * @ret wlen		Length of formatted string (in wide characters)
98
+ */
99
+int efi_snprintf ( wchar_t *wbuf, size_t wsize, const char *fmt, ... ) {
100
+	va_list args;
101
+	int i;
102
+
103
+	va_start ( args, fmt );
104
+	i = efi_vsnprintf ( wbuf, wsize, fmt, args );
105
+	va_end ( args );
106
+	return i;
107
+}
108
+
109
+/**
110
+ * Version of efi_vsnprintf() that accepts a signed buffer size
111
+ *
112
+ * @v wbuf		Buffer into which to write the string
113
+ * @v swsize		Size of buffer (in wide characters)
114
+ * @v fmt		Format string
115
+ * @v args		Arguments corresponding to the format string
116
+ * @ret wlen		Length of formatted string (in wide characters)
117
+ */
118
+int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
119
+		     va_list args ) {
120
+
121
+	/* Treat negative buffer size as zero buffer size */
122
+	if ( swsize < 0 )
123
+		swsize = 0;
124
+
125
+	/* Hand off to vsnprintf */
126
+	return efi_vsnprintf ( wbuf, swsize, fmt, args );
127
+}
128
+
129
+/**
130
+ * Version of efi_vsnprintf() that accepts a signed buffer size
131
+ *
132
+ * @v wbuf		Buffer into which to write the string
133
+ * @v swsize		Size of buffer (in wide characters)
134
+ * @v fmt		Format string
135
+ * @v ...		Arguments corresponding to the format string
136
+ * @ret wlen		Length of formatted string (in wide characters)
137
+ */
138
+int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt, ... ) {
139
+	va_list args;
140
+	int len;
141
+
142
+	/* Hand off to vssnprintf */
143
+	va_start ( args, fmt );
144
+	len = efi_vssnprintf ( wbuf, swsize, fmt, args );
145
+	va_end ( args );
146
+	return len;
147
+}

Loading…
Откажи
Сачувај